曾经在N年前,也写过一个阿拉伯数字转大写金额的代码,但那时候对正则还不是很了解,Replace写的一长串一长串,现在用正则后,妥妥的几次Replace搞定,与其它转换代码相比,当然也要有点独特(或者说是画蛇添足)的地方,同时支持简体与繁体,好歹台湾同胞们用的都是繁体不是?当然大写金额国内也认可繁体的说……
代码不多,就一个枚举和一个静态类
枚举ChineseLanguage用于确认要转化成哪种中文
public enum ChineseLanguage { /// <summary> /// 简体 /// </summary> SimplifiedChinese = 0, /// <summary> /// 繁体 /// </summary> TraditionalChinese = 1 }ConvertIAmount为静态类,包含一个公开的扩展方法和两个私有的静态方法
using System.Text; using System.Text.RegularExpressions; public static class ConvertIAmount { /// <summary> /// 中文的单位,不采用兆京等易产生误解的单位 /// </summary> private static readonly string[] ChineseNumberUnits = { "万拾佰仟亿", "萬拾佰仟億" }; /// <summary> /// 中文的数字 /// </summary> private static readonly string[] ChineseNumbers = { "零壹贰叁肆伍陆柒捌玖", "零壹貳叁肆伍陸柒捌玖" }; /// <summary> /// RMB计价单位 /// </summary> private static readonly string[] RMBUnits = { "圆角分", "圓角分" }; /// <summary> /// 将阿拉伯数字转换为中文人民币书写 /// </summary> /// <param name="number">要转换的阿拉伯数字</param> /// <param name="language">要转化为哪种中文,默认简体</param> /// <returns></returns> public static string ConvertChIAmount(this decimal number, ChineseLanguage language = ChineseLanguage.SimplifiedChinese) { if (number < 0) { throw new Exception("The number you want to change must be greater then zero."); } var integerPartNumber = decimal.ToUInt64(number);//整数部分 string integerPart = ConvertIntegerPart(integerPartNumber, language); string decimalPart = ConvertDecimalPart((byte)((number - integerPartNumber) * 100), language);//低于二位的小数直接舍弃,不存在什么进制 if (string.IsNullOrEmpty(decimalPart)) { //不包含小数时,增加 整 标志 return string.Format("{0} 整", integerPart); } else { //组织字符串并移除零圆(零圓) return string.Format("{0} {1}", integerPart, decimalPart).Trim(ChineseNumbers[0][0], RMBUnits[0][0], RMBUnits[1][0]).Trim(); } } /// <summary> /// 转化整数部分 /// </summary> /// <param name="number">ulong.Max=1844 6744 0737 0955 1615</param> /// <param name="language"></param> /// <returns></returns> private static string ConvertIntegerPart(ulong number, ChineseLanguage language) { string numbers = ChineseNumbers[(int)language]; string rmbUnits = RMBUnits[(int)language]; string numberUnits = ChineseNumberUnits[(int)language]; string returnStr; StringBuilder tmp = new StringBuilder(); tmp.Append(rmbUnits[0]);//圆(圓) for (var i = 0; ; i++) { if (i > 0) { if (i % 8 == 0) { tmp.Insert(0, numberUnits[4]);//亿(億) } else { tmp.Insert(0, numberUnits[i % 4]);//万(萬)拾佰仟 } } var tmpInt = number % 10; tmp.Insert(0, numbers[(int)tmpInt]); number /= 10; if (number == 0) { break; } } string zero = numbers[0].ToString(); //将 零[拾佰仟] 替换成 零 returnStr = Regex.Replace(tmp.ToString(), string.Format("{0}[{1}{2}{3}]", numbers[0], numberUnits[1], numberUnits[2], numberUnits[3]), zero); //将 零{2,} 替换成 零 returnStr = Regex.Replace(returnStr, string.Format("[{0}]{{2,}}", numbers[0]), zero); //将 零(?=[万亿]) 替换成 空格 returnStr = Regex.Replace(returnStr, string.Format("{0}(?=[{1}{2}])", numbers[0], numberUnits[0], numberUnits[4]), string.Empty); //将 (?<=[亿])万 替换成 空格 returnStr = Regex.Replace(returnStr, string.Format("(?<=[{0}]){1}", numberUnits[4], numberUnits[0]), string.Empty); //将 (?<=[万拾佰仟亿])零(?=圆) 替换成 空格 returnStr = Regex.Replace(returnStr, string.Format("(?<=[{0}]){1}(?={2})", numberUnits, numbers[0], rmbUnits[0]), string.Empty); return returnStr; } /// <summary> /// 转化小数部分 /// </summary> /// <param name="number"></param> /// <param name="language"></param> /// <returns></returns> private static string ConvertDecimalPart(byte number, ChineseLanguage language) { string returnStr = string.Empty; if (number > 0) { string numbers = ChineseNumbers[(int)language]; string rmbUnits = RMBUnits[(int)language]; returnStr = string.Format("{0}{1}{2}{3}", numbers[number / 10], rmbUnits[1], numbers[number % 10], rmbUnits[2]); //将 零[角分] 替换成 空格 returnStr = Regex.Replace(returnStr, string.Format("{0}[{1}{2}]", numbers[0], rmbUnits[1], rmbUnits[2]), string.Empty); } return returnStr; } }
下面是测试代码
Console.WriteLine(ConvertIAmount.ConvertChIAmount(10000000100010.01m, ChineseLanguage.TraditionalChinese));//壹拾萬億零壹拾萬零壹拾圓 壹分 Console.WriteLine(ConvertIAmount.ConvertChIAmount(10000000100010.01m));壹拾万亿零壹拾万零壹拾圆 壹分 Console.WriteLine(ConvertIAmount.ConvertChIAmount(12060000100010.01m));//壹拾贰万零陆佰亿零壹拾万零壹拾圆 壹分 Console.WriteLine(ConvertIAmount.ConvertChIAmount(12060000100010.01m, ChineseLanguage.TraditionalChinese));//壹拾貳萬零陸佰億零壹拾萬零壹拾圓 壹分写完看到一个帖子的29楼(方法里面double要改成decimal,不然在大数字的情况下会精度丢失)我就自卑了