数字转义汉字数字显示的简单研究

最近有个需求,需要显示汉字数字,比如一二三四五…这样子,问题看起来挺简单,但我没有找到有自带这样的转换的方法,数字转汉字数字,挺有意思的,就简单研究了一下;
百度了一下,有个基本的思路就是预定义有个数字,直接取:

var baseStr = new List<string>() { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十",};

直接按下标就能实现1~10的转换了;
但是超过10怎么办呢?不可能把所有数字预定义啊。那就组合拼装一下:

var baseStr = new List<string>() { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九", };
var signs = new List<string>() { "十", "百", "千", "万",}

一下子就把范围扩大大99999了,通过各个位数的值,进行转换,这样你就可以会得到 “一十”,“一十一”,“一百零” ,“三千零零五”,这样不符合表达的结果;

算了,文章不会写。总之,经过一系列的演化,直接上源码吧;

准备好预定义的汉字数字(兆后面都是百度来的):

var signs = new List<string>() { "十", "百", "千", "万", "亿", "兆", "京", "垓", "秭", "穰", "沟", "涧", "正", "载", "极", "恒河沙", "阿僧祇", "那由他", "不可思议", "无量大数" };
            var baseStr = new List<string>() { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九", };

做个初始判断,支持正负号:

var charFirst = numStr.First();
            int startNumIndex = 0;
            string firstSign = string.Empty;
            if (!char.IsNumber(charFirst))
            {
                if (!charFirst.Equals('-'))
                {
                    if (!charFirst.Equals('+'))
                    {
                        outString = $"输入参数第一位“ {charFirst} ”既不是数字也不是正负符号。";
                        return false;
                    }

                    firstSign = "正";
                }
                else
                {
                    firstSign = "负";
                }

                startNumIndex = 1;
            }

            var realStr = numStr.Substring(startNumIndex, numStr.Length - startNumIndex);
            realStr.Trim();
            realStr.ToList().RemoveAll(p => !char.IsNumber(p));
            var strTemp = realStr.ToString();
            if (string.IsNullOrEmpty(strTemp))
            {
                outString = $"输入参数“ {numStr} ”没有数字!";
                return false;
            }

从各位开始判断,拼接字符串:

var werishu = strTemp.Length;
            var strReverse = strTemp.Reverse().ToList();

            var strResult = string.Empty;
            bool isShowZero = ShowZero();
            for (int index = 0; index < werishu; index++)
            {
                var ch = strReverse[index];
                var tempNumber = int.Parse(ch.ToString());
                strResult = $"{Trans(tempNumber, index - 1, isShowZero)}{strResult}";
                if (tempNumber == 0)
                {
                    isShowZero = false;
                }
            }

            outString = $"{firstSign}{strResult}";
            return true;

是否显示“零的判断”,处理“一百”,“一千”,“一万” 这样的情况

bool ShowZero()
            {
                var sub1 = strTemp.IndexOf("0");
                bool need0 = false;
                if (sub1 != -1)
                {
                    var less = strTemp.Length - sub1 - 1;
                    if (werishu == 1 ||
                        (less > 0 && strTemp.Substring(sub1 + 1).Count(p => p.Equals('0')) != less))
                    {// 不是连续的0,要保留显示“零”
                        need0 = true;
                    }
                }

                return need0;
            }

转换逻辑,按位取对应数字和单位

string Trans(int value, int signIndex, bool showZero)
            {
                if (value == 1 && signIndex == 0)
                {
                    return signs[signIndex];
                }

                var strSign = signs[0];
                strSign = CalSign(signIndex); 
                var tempResult = $"{GeStr(value, showZero)}{strSign }";
                return tempResult;
            }

获取对应数字的逻辑:

string GeStr(int baseStrIdex, bool showZero)
            {
                if (showZero)
                {
                    return baseStr[baseStrIdex];
                }

                return baseStrIdex == 0 ? string.Empty : baseStr[baseStrIdex];
            }

重点来了,单位计算,比如十万~千万,是单位与单位的拼接:

string CalSign(int signIndex)
            {
                var strSign = string.Empty;
                var realSignIndex = signIndex;
                if (realSignIndex < 4)
                {
                    return GetSignStr(realSignIndex);
                }
                 
                int signSecond = 4; // 到亿
                if (realSignIndex < 7)
                {// 到亿
                    return $"{GetSignStr(signIndex - signSecond)}";
                }

                if (realSignIndex == 7)
                {
                    return GetSignStr(signSecond);
                }

                realSignIndex -= 7;
                var signLen = 4;
                var n = realSignIndex / signLen;
                if (realSignIndex == n * signLen)
                {
                    return GetSignStr(n + signSecond);
                }

                return strSign = $"{GetSignStr(realSignIndex - (n * signLen) - 1)}";

                string GetSignStr(int indexTemp)
                {
                    return indexTemp == -1 ? string.Empty : signs[indexTemp];
                }
            }

至此,完成!

欢迎加入我的QQ群,一起探讨Revit二次开发技术!

QQ群:631436766

全部带入如下,复制粘贴即可

public bool GetChineseNumber(string numStr, out string outString)
        {
            outString = string.Empty;
            if (!CheckValid(numStr, ref outString, out var strTemp, out var firstSign))
            {
                return false;
            }

            var signs = new List<string>() { "十", "百", "千", "万", "亿", "兆", "京", "垓", "秭", "穰", "沟", "涧", "正", "载", "极", "恒河沙", "阿僧祇", "那由他", "不可思议", "无量大数" };
            var baseStr = new List<string>() { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九", };

            bool isShowZero = IsShowZero(strTemp);
            var len = strTemp.Length;
            var strReverse = strTemp.Reverse().ToList();
            var strResult = string.Empty;
            for (int index = 0; index < len; index++)
            {
                var ch = strReverse[index];
                var tempNumber = int.Parse(ch.ToString());
                var signIndex = index - 1;
                string tempResult;
                if (tempNumber == 1 && signIndex == 0 && len == 2)
                {
                    tempResult = signs[signIndex];
                }
                else
                { 
                    var strSign = CalSign(signIndex, signs);
                    var showZero = isShowZero && index > 0;
                    tempResult = $"{GeStr(tempNumber, showZero, baseStr)}{strSign}";
                }

                strResult = $"{tempResult}{strResult}";
                if (tempNumber == 0)
                {
                    isShowZero = false;
                }
            }

            outString = $"{firstSign}{strResult}";
            return true;
        }
         
        private bool CheckValid(string numStr, ref string outString, out string realNumberString, out string firstSign)
        {
            realNumberString = string.Empty;
            var charFirst = numStr.First();
            var startNumIndex = 0;
            firstSign = string.Empty;
            if (!char.IsNumber(charFirst))
            {
                if (!charFirst.Equals('-'))
                {
                    if (!charFirst.Equals('+'))
                    {
                        outString = $"输入参数第一位“ {charFirst} ”既不是数字也不是正负符号。";
                        return false;
                    }

                    firstSign = "正";
                }
                else
                {
                    firstSign = "负";
                }

                startNumIndex = 1;
            }

            var realStr = numStr.Substring(startNumIndex, numStr.Length - startNumIndex);
            realStr.Trim();
            realStr.ToList().RemoveAll(p => !char.IsNumber(p));
            realNumberString = realStr.ToString();
            if (string.IsNullOrEmpty(realNumberString))
            {
                outString = $"输入参数“ {numStr} ”没有数字!";
                return false;
            }

            return true;
        }

        private string CalSign(int signIndex, List<string> signs)
        {
            var realSignIndex = signIndex;
            if (realSignIndex < 4)
            {
                return GetSignStr(realSignIndex);
            }

            int signSecond = 4; // 到亿
            if (realSignIndex < 7)
            {// 到亿
                return $"{GetSignStr(signIndex - signSecond)}";
            }

            if (realSignIndex == 7)
            {
                return GetSignStr(signSecond);
            }

            realSignIndex -= 7;
            var signLen = 4;
            var n = realSignIndex / signLen;
            if (realSignIndex == n * signLen)
            {
                return GetSignStr(n + signSecond);
            }

            string strSign;
            return strSign = $"{GetSignStr(realSignIndex - (n * signLen) - 1)}";

            string GetSignStr(int indexTemp)
            {
                return indexTemp == -1 ? string.Empty : signs[indexTemp];
            }
        }

        private string GeStr(int baseStrIdex, bool showZero, List<string> baseStr)
        {
            if (showZero)
            {
                return baseStr[baseStrIdex];
            }

            return baseStrIdex == 0 ? string.Empty : baseStr[baseStrIdex];
        }

        private bool IsShowZero(string strTemp)
        {
            int len = strTemp.Length;
            var sub1 = strTemp.IndexOf("0");
            bool need0 = false;
            if (sub1 != -1)
            {
                var less = strTemp.Length - sub1 - 1;
                if (len == 1 ||
                    (less > 0 && strTemp.Substring(sub1 + 1).Count(p => p.Equals('0')) != less))
                {// 不是连续的0,要保留显示“零”
                    need0 = true;
                }
            }

            return need0;
        }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值