NumberToUpper数字转中文详解
使用时需开启unsafe选项
构造函数有4个参数
number : 数字文本
issimplified : 是否只使用简体中文,默认:false
ismoney : 是否是金额模式(忽略小数点后3位,并加上单位"元,角,分或整"),否认:true
verybig : 是否开启大数字文本模式(接受15位以上整数,及10位以上小数),否认:false
using system;
using system.componentmodel;
using system.text;
using system.text.regularexpressions;
namespace blqw
{
public static class numbertoupper
{
#region 固定参数
//^[-+]?\d*(?<point>[.])?\d*$
readonly static regex checknumber = new regex(@"^[\s\t]*0*(?<integer>[-+]?\d*)[.]?(?<decimal>\d*[1-9])?[0]*[\s\t]*$", regexoptions.compiled);
readonly static string[] uppernumbers =
{
"零壹貳叁肆伍陸柒捌玖點",
"零一二三四五六七八九点"
};
readonly static string[] numberunits =
{
"仟萬拾佰億負",
"千万十百亿负"
};
readonly static string[] moneyunits =
{
"圓角分",
"元角分"
};
#endregion
/// <summary> 将数字文本转换成大写
/// </summary>
/// <param name="number">数字文本</param>
/// <param name="issimplified">是否只使用简体中文,默认:否</param>
/// <param name="ismoney">是否是金额模式(忽略小数点后3位,并加上单位"元,角,分或整"),否认:是</param>
/// <param name="verybig">是否开启大数字文本模式(接受15位以上整数,及10位以上小数),否认:否</param>
public static string go(string number, bool issimplified = false, bool ismoney = true, bool verybig = false)
{
if (number == null)
{
throw new argumentnullexception("number", "number不能为空");
}
//number = number.trim(' ', '\t'); //去掉多余的空格,制表符
var m = checknumber.match(number);
if (m.success == false)
{
throw new argumentexception("number不是数字", "number");
}
unsafe
{
fixed (char* p = number)
fixed (char* upnum = uppernumbers[issimplified.gethashcode()])
fixed (char* numut = numberunits[issimplified.gethashcode()])
fixed (char* monut = moneyunits[issimplified.gethashcode()])
{
var mdec = m.groups["decimal"];
var mint = m.groups["integer"];
if (mint.length > 15 && verybig == false)
{
throw new argumentexception("不建议转换超过15位的整数,除非将verybig参数设置为true", "number");
}
if (mdec.length > 10 && verybig == false)
{
throw new argumentexception("不建议转换超过10位的小,除非将verybig参数设置为true", "number");
}
string integer = parseinteger(p + mint.index, p + mint.index + mint.length - 1, upnum, numut);
if (mdec.success == false)
{
string unit = null;
if (ismoney)
unit = monut[0].tostring() + "整";
return integer + unit;
}
else
{
if (ismoney)
{
string jiao = upnum[p[mdec.index] - '0'].tostring();
string fen = mdec.length == 1 ? "0" : upnum[p[mdec.index + 1] - '0'].tostring();
if (jiao != "0")
{
jiao += monut[1];
}
if (fen != "0")
{
jiao += fen + monut[2];
}
return integer + monut[0].tostring() + jiao;
}
else
{
return integer + parsedecimal(p + mdec.index, p + mdec.index + mdec.length - 1, upnum);
}
}
}
}
}
//操作小数部分
static unsafe string parsedecimal(char* p, char* end, char* upnum)
{
stringbuilder sb = new stringbuilder((int)(end - p));
sb.append(upnum[10]);
while (p <= end)
{
sb.append(upnum[*p - '0']);
p++;
}
return sb.tostring();
}
//操作整数部分,为了效率不写递归.....
static unsafe string parseinteger(char* p, char* end, char* upnum, char* numut)
{
int length = (int)(end - p) + 1;
stringbuilder sb = new stringbuilder(length * 3);
if (*p == '-')
{
sb.append(numut[5]);
p++;
length--;
if (*p == '.')
{
sb.append(upnum[5]);
}
}
else if (*p == '+')
{
p++;
length--;
}
bool ling = false;
bool yi = false;
bool wan = false;
while (p <= end)
{
int num = *p - '0'; //获得当前的数0-9
if (num != 0 && ling == true)//需要加 零
{
sb.append(upnum[0]);
ling = false; //重置 参数
}
if (length % 8 == 1) //判断是否在"亿"位
{ //如果是
int n = length / 8; //计算应该有几个"亿"
if (num != 0 || yi == true) //判断是否需要加 单位
{
if (num != 0) //如果不为 0
{
sb.append(upnum[num]); //加入字符串
}
if (n > 0) sb.append(numut[4], n);
if (ling) ling = false; //重置 参数
yi = false; //重置 参数
if (wan) wan = false; //重置 参数
}
}
else //十千百万
{
var uindex = length % 4; //单位索引
if (uindex == 1) //判断是否在"万"位
{
if (num != 0 || wan == true) //判断是否需要加 单位
{
if (num != 0) //如果不为 0
{
sb.append(upnum[num]); //加入字符串
}
sb.append(numut[uindex]);
if (ling) ling = false; //重置 参数
wan = false; //重置 参数
if (!yi) yi = true; //设定 参数
}
}
else //十千百
{
if (num != 0) //如果不为 0
{
if ((uindex == 2 && num == 1) == false) //排除 "一十二" 只显示 "十二"
{
sb.append(upnum[num]); //加入字符串
}
sb.append(numut[uindex]);//加入单位
if (!yi) yi = true; //设定 参数
if (!wan) wan = true; //设定 参数
}
else if (ling == false)
{
ling = true;
}
}
}
length--;
p++;
}
return sb.tostring();
}
}
}
var str = numbertoupper.go("467412346546454.4564768");
console.writeline(str);
str = numbertoupper.go("467412346546454.4564768", true);
console.writeline();
console.writeline(str);
str = numbertoupper.go("467412346546454.4564768", false, false);
console.writeline();
console.writeline(str);
str = numbertoupper.go("7672313576513214657465413244563203246.1235", false, false, true);
console.writeline();
console.writeline(str);