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