From b792ad4e0808ecb943573e6c58dd95b739b2b9dc Mon Sep 17 00:00:00 2001 From: totalo Date: Wed, 10 Mar 2021 14:48:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=94=AF=E6=8C=81=E6=B1=89=E5=AD=97?= =?UTF-8?q?=E8=BD=AC=E9=98=BF=E6=8B=89=E4=BC=AF=E6=95=B0=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/convert/ChineseNameValue.java | 52 +++++++++++ .../core/convert/NumberChineseFormatter.java | 87 +++++++++++++++++++ .../convert/NumberChineseFormatterTest.java | 27 ++++-- 3 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 hutool-core/src/main/java/cn/hutool/core/convert/ChineseNameValue.java diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/ChineseNameValue.java b/hutool-core/src/main/java/cn/hutool/core/convert/ChineseNameValue.java new file mode 100644 index 000000000..61822624e --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/convert/ChineseNameValue.java @@ -0,0 +1,52 @@ +package cn.hutool.core.convert; + +/** + * @author totalo + * @since 5.6.0 + * 中文转数字结构 + */ +public final class ChineseNameValue { + /** + * 中文权名称 + */ + String name; + /** + * 10的倍数值 + */ + int value; + + /** + * 是否为节权位 + */ + boolean secUnit; + + public ChineseNameValue(String name, int value, boolean secUnit) { + this.name = name; + this.value = value; + this.secUnit = secUnit; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public boolean isSecUnit() { + return secUnit; + } + + public void setSecUnit(boolean secUnit) { + this.secUnit = secUnit; + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/NumberChineseFormatter.java b/hutool-core/src/main/java/cn/hutool/core/convert/NumberChineseFormatter.java index 1b386f77b..7b18ecce8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/NumberChineseFormatter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/NumberChineseFormatter.java @@ -33,6 +33,18 @@ public class NumberChineseFormatter { **/ private static final String[] TRADITIONAL_UNITS = {"", "拾", "佰", "仟"}; + /** + * 汉字转阿拉伯数字的 + */ + private static final ChineseNameValue[] CHINESE_NAME_VALUE = { + new ChineseNameValue("十", 10, false), + new ChineseNameValue("百", 100, false), + new ChineseNameValue("千", 1000, false), + new ChineseNameValue("万", 10000, true), + new ChineseNameValue("亿", 100000000, true), + }; + + /** * 阿拉伯数字转换成中文,小数点后四舍五入保留两位. 使用于整数、小数的转换. * @@ -193,4 +205,79 @@ public class NumberChineseFormatter { } return chineseStr.toString(); } + + /** + * 把中文转换为数字 如 二百二 220 + * @see https://www.d5.nz/read/sfdlq/text-part0000_split_030.html + * @param chinese 中文字符 + * @return + */ + public static int chineseToNumber(String chinese) { + int pos = 0; + int rtn = 0; + int section = 0; + int number = 0; + boolean secUnit = false; + while (pos < chinese.length()) { + int num = chineseToValue(chinese.substring(pos, pos + 1)); + if (num >= 0) { + number = num; + pos += 1; + if (pos >= chinese.length()) { + section += number; + rtn += section; + break; + } + } else { + int unit = 1; + int tmp = chineseToUnit(chinese.substring(pos, pos + 1)); + if (tmp != -1) { + unit = CHINESE_NAME_VALUE[tmp].getValue(); + secUnit = CHINESE_NAME_VALUE[tmp].isSecUnit(); + } + if (secUnit) { + section = (section + number) * unit; + rtn += section; + section = 0; + } else { + section += (number * unit); + } + number = 0; + pos += 1; + if (pos >= chinese.length()) { + rtn += section; + break; + } + } + } + return rtn; + } + + /** + * 中文到数字的转换 + * @param chinese + * @return + */ + private static int chineseToValue(String chinese) { + for (int i = 0; i < SIMPLE_DIGITS.length; i++) { + if (SIMPLE_DIGITS[i].equals(chinese)) { + return i; + } + } + return -1; + } + + /** + * 查找对应的权 + * @param chinese + * @return + */ + private static int chineseToUnit(String chinese) { + for (int i = 0; i < CHINESE_NAME_VALUE.length; i++) { + if (CHINESE_NAME_VALUE[i].getName().equals(chinese)) { + return i; + } + } + return -1; + } } diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/NumberChineseFormatterTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/NumberChineseFormatterTest.java index 09404d074..53167e57a 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/NumberChineseFormatterTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/NumberChineseFormatterTest.java @@ -4,7 +4,7 @@ import org.junit.Assert; import org.junit.Test; public class NumberChineseFormatterTest { - + @Test public void formatTest() { String f1 = NumberChineseFormatter.format(10889.72356, false); @@ -24,7 +24,7 @@ public class NumberChineseFormatterTest { f1 = NumberChineseFormatter.format(0.05, false); Assert.assertEquals("零点零五", f1); } - + @Test public void formatTest2() { String f1 = NumberChineseFormatter.format(-0.3, false, false); @@ -33,7 +33,7 @@ public class NumberChineseFormatterTest { f1 = NumberChineseFormatter.format(10, false, false); Assert.assertEquals("一十", f1); } - + @Test public void formatTraditionalTest() { String f1 = NumberChineseFormatter.format(10889.72356, true); @@ -53,15 +53,15 @@ public class NumberChineseFormatterTest { f1 = NumberChineseFormatter.format(0.05, true); Assert.assertEquals("零点零伍", f1); } - + @Test public void digitToChineseTest() { String digitToChinese = Convert.digitToChinese(12412412412421.12); Assert.assertEquals("壹拾贰万肆仟壹佰贰拾肆亿壹仟贰佰肆拾壹万贰仟肆佰贰拾壹元壹角贰分", digitToChinese); - + String digitToChinese2 = Convert.digitToChinese(12412412412421D); Assert.assertEquals("壹拾贰万肆仟壹佰贰拾肆亿壹仟贰佰肆拾壹万贰仟肆佰贰拾壹元整", digitToChinese2); - + String digitToChinese3 = Convert.digitToChinese(2421.02); Assert.assertEquals("贰仟肆佰贰拾壹元零贰分", digitToChinese3); } @@ -79,4 +79,19 @@ public class NumberChineseFormatterTest { s = NumberChineseFormatter.numberCharToChinese('A', false); Assert.assertEquals("A", s); } + + @Test + public void chineseToNumberTest(){ + Assert.assertEquals(0, NumberChineseFormatter.chineseToNumber("零")); + + Assert.assertEquals(102, NumberChineseFormatter.chineseToNumber("一百零二")); + + Assert.assertEquals(112, NumberChineseFormatter.chineseToNumber("一百一十二")); + + Assert.assertEquals(1012, NumberChineseFormatter.chineseToNumber("一千零一十二")); + + Assert.assertEquals(1000000, NumberChineseFormatter.chineseToNumber("一百万")); + + Assert.assertEquals(2000100112, NumberChineseFormatter.chineseToNumber("二十亿零一十万零一百一十二")); + } }