阿拉伯数字转大写金额(支持简体和繁体)

曾经在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,不然在大数字的情况下会精度丢失)我就自卑了

你可能感兴趣的:(C#,正则,大写金额)