Browse Source

增加数字转中文。

懒得勤快 6 years ago
parent
commit
a83347df15

+ 1 - 1
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netcoreapp3.0</TargetFramework>
-    <Version>2.2.7</Version>
+    <Version>2.2.7.1</Version>
     <Authors>懒得勤快</Authors>
     <Company>masuit.com</Company>
     <Description>包含一些常用的操作类,大都是静态类,加密解密,反射操作,硬件信息,字符串扩展方法,日期时间扩展操作,大文件拷贝,图像裁剪,html处理,验证码、NoSql等常用封装。

+ 14 - 0
Masuit.Tools.Core/Masuit.Tools.Core.xml

@@ -6395,6 +6395,20 @@
             <summary>Returns a string that represents the current object.</summary>
             <returns>A string that represents the current object.</returns>
         </member>
+        <member name="M:Masuit.Tools.Strings.NumberFormater.ToChineseNumber(System.Double)">
+            <summary>
+            转换为中文数字格式
+            </summary>
+            <param name="num">123.45</param>
+            <returns></returns>
+        </member>
+        <member name="M:Masuit.Tools.Strings.NumberFormater.ToChineseMoney(System.Double)">
+            <summary>
+            数字转中文金额大写
+            </summary>
+            <param name="number">22.22</param>
+            <returns></returns>
+        </member>
         <member name="T:Masuit.Tools.Strings.Template">
             <summary>
             模版引擎

+ 163 - 9
Masuit.Tools.Core/Strings/NumberFormater.cs

@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
+using System.Text.RegularExpressions;
 
 namespace Masuit.Tools.Strings
 {
@@ -82,25 +84,177 @@ namespace Masuit.Tools.Strings
         /// <returns></returns>
         public long FromString(string str)
         {
-            long result = 0;
             int j = 0;
-            foreach (var ch in new string(str.ToCharArray().Reverse().ToArray()))
+            return new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch)).Sum(ch => Characters.IndexOf(ch) * (long)Math.Pow(Length, j++));
+        }
+
+        /// <summary>Returns a string that represents the current object.</summary>
+        /// <returns>A string that represents the current object.</returns>
+        public override string ToString()
+        {
+            return Length + "模式";
+        }
+        // 转换数字 
+        private static char ToNum(char x)
+        {
+            string strChnNames = "零一二三四五六七八九";
+            string strNumNames = "0123456789";
+            return strChnNames[strNumNames.IndexOf(x)];
+        }
+
+        // 转换万以下整数 
+        private static string ChangeInt(string x)
+        {
+            string[] strArrayLevelNames = { "", "十", "百", "千" };
+            string ret = "";
+            int i;
+            for (i = x.Length - 1; i >= 0; i--)
+            {
+                if (x[i] == '0')
+                {
+                    ret = ToNum(x[i]) + ret;
+                }
+                else
+                {
+                    ret = ToNum(x[i]) + strArrayLevelNames[x.Length - 1 - i] + ret;
+                }
+            }
+
+            while ((i = ret.IndexOf("零零", StringComparison.Ordinal)) != -1)
+            {
+                ret = ret.Remove(i, 1);
+            }
+
+            if (ret[^1] == '零' && ret.Length > 1)
+            {
+                ret = ret.Remove(ret.Length - 1, 1);
+            }
+
+            if (ret.Length >= 2 && ret.Substring(0, 2) == "一十")
             {
-                if (Characters.Contains(ch))
+                ret = ret.Remove(0, 1);
+            }
+
+            return ret;
+        }
+
+        // 转换整数 
+        private static string ToInt(string x)
+        {
+            int len = x.Length;
+            string result;
+            string temp;
+            if (len <= 4)
+            {
+                result = ChangeInt(x);
+            }
+            else if (len <= 8)
+            {
+                result = ChangeInt(x.Substring(0, len - 4)) + "万";
+                temp = ChangeInt(x.Substring(len - 4, 4));
+                if (temp.IndexOf("千", StringComparison.Ordinal) == -1 && !string.IsNullOrEmpty(temp))
+                {
+                    result += "零" + temp;
+                }
+                else
+                {
+                    result += temp;
+                }
+            }
+            else
+            {
+                result = ChangeInt(x.Substring(0, len - 8)) + "亿";
+                temp = ChangeInt(x.Substring(len - 8, 4));
+                if (temp.IndexOf("千", StringComparison.Ordinal) == -1 && !string.IsNullOrEmpty(temp))
+                {
+                    result += "零" + temp;
+                }
+                else
+                {
+                    result += temp;
+                }
+
+                result += "万";
+                temp = ChangeInt(x.Substring(len - 4, 4));
+                if (temp.IndexOf("千", StringComparison.Ordinal) == -1 && !string.IsNullOrEmpty(temp))
+                {
+                    result += "零" + temp;
+                }
+                else
                 {
-                    result += Characters.IndexOf(ch) * (long)Math.Pow(Length, j);
-                    j++;
+                    result += temp;
                 }
             }
+            int i;
+            if ((i = result.IndexOf("零万", StringComparison.Ordinal)) != -1)
+            {
+                result = result.Remove(i + 1, 1);
+            }
+
+            while ((i = result.IndexOf("零零", StringComparison.Ordinal)) != -1)
+            {
+                result = result.Remove(i, 1);
+            }
+
+            if (result[^1] == '零' && result.Length > 1)
+            {
+                result = result.Remove(result.Length - 1, 1);
+            }
 
             return result;
         }
 
-        /// <summary>Returns a string that represents the current object.</summary>
-        /// <returns>A string that represents the current object.</returns>
-        public override string ToString()
+        /// <summary>
+        /// 转换为中文数字格式
+        /// </summary>
+        /// <param name="num">123.45</param>
+        /// <returns></returns>
+        public static string ToChineseNumber(double num)
         {
-            return Length + "模式";
+            var x = num.ToString(CultureInfo.CurrentCulture);
+            if (x.Length == 0)
+            {
+                return "";
+            }
+
+            string result = "";
+            if (x[0] == '-')
+            {
+                result = "负";
+                x = x.Remove(0, 1);
+            }
+            if (x[0].ToString() == ".")
+            {
+                x = "0" + x;
+            }
+
+            if (x[^1].ToString() == ".")
+            {
+                x = x.Remove(x.Length - 1, 1);
+            }
+
+            if (x.IndexOf(".") > -1)
+            {
+                result += ToInt(x.Substring(0, x.IndexOf("."))) + "点" + x.Substring(x.IndexOf(".") + 1).Aggregate("", (current, t) => current + ToNum(t));
+            }
+            else
+            {
+                result += ToInt(x);
+            }
+
+            return result;
+        }
+
+        /// <summary>
+        /// 数字转中文金额大写
+        /// </summary>
+        /// <param name="number">22.22</param>
+        /// <returns></returns>
+        public static string ToChineseMoney(double number)
+        {
+            string s = number.ToString("#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A");
+            string d = Regex.Replace(s, @"((?<=-|^)[^1-9]*)|((?'z'0)[0A-E]*((?=[1-9])|(?'-z'(?=[F-L\.]|$))))|((?'b'[F-L])(?'z'0)[0A-L]*((?=[1-9])|(?'-z'(?=[\  .]|$))))", "${b}${z}");
+            return Regex.Replace(d, ".", m => "负元空零壹贰叁肆伍陆柒捌玖空空空空空空空分角拾佰仟萬億兆京垓秭穰"[m.Value[0] - '-'].ToString());
         }
     }
 }

+ 26 - 0
Masuit.Tools.UnitTest/NumberFormaterTest.cs

@@ -30,5 +30,31 @@ namespace Masuit.Tools.UnitTest
             string output = nf.ToString(expected);
             Assert.Equal(input, output);
         }
+
+        [Fact]
+        public void Can_ConvertAnyNum2Chinese()
+        {
+            // arrange
+            double num = 1234567809.321;
+
+            // act
+            var chineseNumber = NumberFormater.ToChineseNumber(num);
+
+            // assert
+            Assert.Equal("十二亿三千四百五十六万七千八百零九点三二一", chineseNumber);
+        }
+
+        [Fact]
+        public void Can_ConvertAnyNum2ChineseMoney()
+        {
+            // arrange
+            double num = 123456789.321;
+
+            // act
+            var chineseNumber = NumberFormater.ToChineseMoney(num);
+
+            // assert
+            Assert.Equal("壹億贰仟叁佰肆拾伍萬陆仟柒佰捌拾玖元叁角贰分", chineseNumber);
+        }
     }
 }

BIN
Masuit.Tools/Properties/AssemblyInfo.cs


+ 158 - 9
Masuit.Tools/Strings/NumberFormater.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Text.RegularExpressions;
 
 namespace Masuit.Tools.Strings
 {
@@ -48,6 +49,7 @@ namespace Masuit.Tools.Strings
             {
                 throw new ArgumentException("进制最大支持62进制");
             }
+
             Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".Substring(0, bin);
         }
 
@@ -79,25 +81,172 @@ namespace Masuit.Tools.Strings
         /// <returns></returns>
         public long FromString(string str)
         {
-            long result = 0;
             int j = 0;
-            foreach (var ch in new string(str.ToCharArray().Reverse().ToArray()))
+            return new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch)).Sum(ch => Characters.IndexOf(ch) * (long)Math.Pow(Length, j++));
+        }
+
+        /// <summary>Returns a string that represents the current object.</summary>
+        /// <returns>A string that represents the current object.</returns>
+        public override string ToString()
+        {
+            return Length + "模式";
+        }
+        // 转换数字 
+        private static char ToNum(char x)
+        {
+            string strChnNames = "零一二三四五六七八九";
+            string strNumNames = "0123456789";
+            return strChnNames[strNumNames.IndexOf(x)];
+        }
+
+        // 转换万以下整数 
+        private static string ChangeInt(string x)
+        {
+            string[] strArrayLevelNames = { "", "十", "百", "千" };
+            string ret = "";
+            int i;
+            for (i = x.Length - 1; i >= 0; i--)
+            {
+                if (x[i] == '0')
+                {
+                    ret = ToNum(x[i]) + ret;
+                }
+                else
+                {
+                    ret = ToNum(x[i]) + strArrayLevelNames[x.Length - 1 - i] + ret;
+                }
+            }
+
+            while ((i = ret.IndexOf("零零", StringComparison.Ordinal)) != -1)
             {
-                if (Characters.Contains(ch))
+                ret = ret.Remove(i, 1);
+            }
+
+            if (ret[ret.Length - 1] == '零' && ret.Length > 1)
+            {
+                ret = ret.Remove(ret.Length - 1, 1);
+            }
+
+            if (ret.Length >= 2 && ret.Substring(0, 2) == "一十")
+            {
+                ret = ret.Remove(0, 1);
+            }
+
+            return ret;
+        }
+
+        // 转换整数 
+        private static string ToInt(string x)
+        {
+            int len = x.Length;
+            string result;
+            string temp;
+            if (len <= 4)
+            {
+                result = ChangeInt(x);
+            }
+            else if (len <= 8)
+            {
+                result = ChangeInt(x.Substring(0, len - 4)) + "万";
+                temp = ChangeInt(x.Substring(len - 4, 4));
+                if (temp.IndexOf("千", StringComparison.Ordinal) == -1 && !string.IsNullOrEmpty(temp))
+                {
+                    result += "零" + temp;
+                }
+                else
+                {
+                    result += temp;
+                }
+            }
+            else
+            {
+                result = ChangeInt(x.Substring(0, len - 8)) + "亿";
+                temp = ChangeInt(x.Substring(len - 8, 4));
+                if (temp.IndexOf("千", StringComparison.Ordinal) == -1 && !string.IsNullOrEmpty(temp))
+                {
+                    result += "零" + temp;
+                }
+                else
+                {
+                    result += temp;
+                }
+
+                result += "万";
+                temp = ChangeInt(x.Substring(len - 4, 4));
+                if (temp.IndexOf("千", StringComparison.Ordinal) == -1 && !string.IsNullOrEmpty(temp))
+                {
+                    result += "零" + temp;
+                }
+                else
                 {
-                    result += Characters.IndexOf(ch) * (long)Math.Pow(Length, j);
-                    j++;
+                    result += temp;
                 }
             }
+            int i;
+            if ((i = result.IndexOf("零万", StringComparison.Ordinal)) != -1)
+            {
+                result = result.Remove(i + 1, 1);
+            }
+
+            while ((i = result.IndexOf("零零", StringComparison.Ordinal)) != -1)
+            {
+                result = result.Remove(i, 1);
+            }
+
+            if (result[result.Length - 1] == '零' && result.Length > 1)
+            {
+                result = result.Remove(result.Length - 1, 1);
+            }
 
             return result;
         }
 
-        /// <summary>Returns a string that represents the current object.</summary>
-        /// <returns>A string that represents the current object.</returns>
-        public override string ToString()
+        public static string ToChineseNumber(double num)
         {
-            return Length + "模式";
+            var x = num.ToString();
+            if (x.Length == 0)
+            {
+                return "";
+            }
+
+            string result = "";
+            if (x[0] == '-')
+            {
+                result = "负";
+                x = x.Remove(0, 1);
+            }
+            if (x[0].ToString() == ".")
+            {
+                x = "0" + x;
+            }
+
+            if (x[x.Length - 1].ToString() == ".")
+            {
+                x = x.Remove(x.Length - 1, 1);
+            }
+
+            if (x.IndexOf(".") > -1)
+            {
+                result += ToInt(x.Substring(0, x.IndexOf("."))) + "点" + x.Substring(x.IndexOf(".") + 1).Aggregate("", (current, t) => current + ToNum(t));
+            }
+            else
+            {
+                result += ToInt(x);
+            }
+
+            return result;
+        }
+
+        /// <summary>
+        /// 数字转中文
+        /// </summary>
+        /// <param name="number">eg: 22</param>
+        /// <returns></returns>
+        public static string ToChineseMoney(double number)
+        {
+            string s = number.ToString("#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A");
+            string d = Regex.Replace(s, @"((?<=-|^)[^1-9]*)|((?'z'0)[0A-E]*((?=[1-9])|(?'-z'(?=[F-L\.]|$))))|((?'b'[F-L])(?'z'0)[0A-L]*((?=[1-9])|(?'-z'(?=[\  .]|$))))", "${b}${z}");
+            return Regex.Replace(d, ".", m => "负元空零壹贰叁肆伍陆柒捌玖空空空空空空空分角拾佰仟萬億兆京垓秭穰"[m.Value[0] - '-'].ToString());
         }
     }
 }

+ 1 - 1
Masuit.Tools/package.nuspec

@@ -4,7 +4,7 @@
     <!--*-->
     <id>Masuit.Tools</id>
     <!--*-->
-    <version>2.2.6.4</version>
+    <version>2.2.7.1</version>
     <title>Masuit.Tools</title>
     <!--*-->
     <authors>masuit.com</authors>