[源码]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);
我写的文章,除了纯代码,其他的都是想表达一种思想,一种解决方案.希望各位看官不要局限于文章中的现成的代码,要多关注整个文章的主题思路,谢谢!
我发布的代码,没有任何版权,遵守WTFPL协议(如有引用,请遵守被引用代码的协议)
qq群:5946699 希望各位喜爱C#的朋友可以在这里交流学习,分享编程的心得和快乐
我发布的代码,没有任何版权,遵守WTFPL协议(如有引用,请遵守被引用代码的协议)
qq群:5946699 希望各位喜爱C#的朋友可以在这里交流学习,分享编程的心得和快乐