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);

(0)

相关推荐

  • NumberToUpper数字转中文详解

    使用时需开启unsafe选项 构造函数有4个参数 number : 数字文本 isSimplified : 是否只使用简体中文,默认:false isMoney : 是否是金额模式(忽略小数点后3位,并加上单位"元,角,分或整"),否认:true veryBig : 是否开启大数字文本模式(接受15位以上整数,及10位以上小数),否认:false 复制代码 代码如下: using System;using System.ComponentModel;using System.Text;

  • JSON创建键值对(key是中文或者数字)方式详解

    先准备好一个空的json对象 var obj = {}; 1. 最原始的方法 obj.name = 'zhangsan'; //这种方式很简单的添加了一个键值对 //输出:{name:"zhangsan"} //缺点:这边的name不能是对象 /* 比如: var name = 'tom'; obj.name = 'zhangsan'; 输出obj:{name:'zhangsan'} 中文可以使用,但是数字不能使用 obj.家="中国"; obj.88(不能这么使用

  • 基于Django模板中的数字自增(详解)

    Django框架的模板提供了{% for %} 标签来进行循环 例如对集合进行循环是比较简单的 {% for row in v1 %} <div>{{row.name}}</div> {% endfor %} 但是在Django中,并不直接支持形如"int i = 0;i<100;i++" 这样的循环,Django有自己的自增方法 假设v1内有2个元素 1,从1开始正向自增 结果1,2 {% for row in v1 %} <div>{{fo

  • java从控制台接收一个数字的实例详解

    java从控制台接收一个数字的实例详解 功能: 从控制台接收一个数 实现代码: import java.io.*; //引入一个IO流的包 public class helloworld1 { public static void main(String args[]) { try{ //输入流,从键盘接收数 InputStreamReader isr=new InputStreamReader(System.in); BufferedReader br=new BufferedReader(i

  • python正则表达式从字符串中提取数字的思路详解

    python从字符串中提取数字 使用正则表达式,用法如下: ## 总结 ## ^ 匹配字符串的开始. ## $ 匹配字符串的结尾. ## \b 匹配一个单词的边界. ## \d 匹配任意数字. ## \D 匹配任意非数字字符. ## x? 匹配一个可选的 x 字符 (换言之,它匹配 1 次或者 0 次 x 字符). ## x* 匹配0次或者多次 x 字符. ## x+ 匹配1次或者多次 x 字符. ## x{n,m} 匹配 x 字符,至少 n 次,至多 m 次. ## (a|b|c) 要么匹配

  • Python猜数字算法题详解

    今天刷的第一道算法题,先拿一道简单点的试试手,这道题目的要求是: 两个人甲乙在猜数字,甲先从1,2,3三个数字中随机抽3次,结果是guess.乙随后也随机抽三次,结果是answer.然后对比甲乙两个人的结果.示例如下: guess:[1,2,3], answer: [1, 2, 3] 那么结果就是猜对了3次 guess: [1,2,3] answer:[3,2,1] 那么结果就是猜对了1次 guess: [1,2,3], answer:[3, 3,1] 那么结果就是猜对了0次 即将guess和a

  • Python中读取文件名中的数字的实例详解

    我们在使用计算机时,我们创建一个个文件夹,可以节省桌面空间,做好整理归纳.python中,每个文件中有着不同的内容,我们要想使用文件,就要读取文件.本文向大家介绍Python读取文件名中的数字的方法:1.使用正则表达式:2.获取匹配的字符串:3.需要整数,可以使用int:4.生成数字. 第一步:可以使用正则表达式 regex = re.compile(r'\d+') 第二步:然后获取匹配的字符串 regex.findall(filename) 这将返回包含数字的字符串列表. 第三步:如果您实际需

  • Python线性点运算数字图像处理示例详解

    目录 点运算 定义 分类 线性点运算 分段线性点运算 非线性点运算 对数变换 幂次变换 点运算 定义 分类 线性点运算 例子: 分段线性点运算 非线性点运算 对数变换 幂次变换 1. 点运算是否会改变图像内像素点之间的空间位置关系? 点运算是一种像素的逐点运算,它与相邻的像素之间没有运算关系,点运算不会改变图像内像素点之间的空间位置关系. 2. 对图像灰度的拉伸,非线性拉伸与分段线性拉伸的区别? 非线性拉伸不是通过在不同灰度值区间选择不同的线性方程来实现对不同灰度值区间的扩展与压缩,而是在整个灰

  • Java实现猜数字小游戏详解流程

    猜数字游戏 系统自动生成一个随机整数(1-100), 然后由用户输入一个猜测的数字. 如果输入的数字比该随机数小, 提示 "低 了", 如果输入的数字比该随机数大, 提示 "高了" , 如果输入的数字和随机数相等, 则提示 "猜对了 整理思路 1. 我们玩游戏的时候,都有开始游戏和退出游戏 2. 其次,它要生成一个随机数,如果是固定值,哪有什么意思? 3. 再者,我们要输入数字,根据它反馈的情况进行判断和猜测数字的大小 4. 但是我们不可能说一次就判断成功

  • C++数位DP复杂度统计数字问题示例详解

    目录 一.问题描述: 二.问题分析: 1. 抽取题意: 2. 初步思考: 3. 示例分析: 4. 总结规律: 5. 解除约定: 三. 编写代码: 四. 相关例题: Tips:如果你是真的不理解,不要只看,拿出笔来跟着步骤自己分析. 一.问题描述: 一本书的页码从自然数 1 开始顺序编码直到自然数 n .书的页码按照通常的习惯编排, 每个页码不含多余的前导数字 0. 例如, 第 6 页用数字 6 表示而不是 06 或 006等. 数字计数问题要求对给定书的总页码 n,计算书的全部页码分别用到多少次

随机推荐