JAVA中文数字转阿拉伯数字

该代码示例展示了如何利用Hutool工具库中的Dict和NumberUtil类,配合正则表达式ReUtil,将中文数字字符串转换为BigDecimal表示的阿拉伯数字。方法首先创建了一个字典映射中文数字到其对应的数值,然后处理负数和小数情况,最后逐个解析整数和小数部分进行转换。
使用到了Hutool工具, 字典Dict\数字转换工具NumberUtil\正则表达式工具\ReUtil
比较懒就用了这些,都是可替换的.
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.10</version>
</dependency>
public static BigDecimal chinese2Number(String numStr){
        if(StrUtil.isEmpty(numStr)){
            return NumberUtil.toBigDecimal(0);
        }
        Dict baseUnitDict = Dict.create().set("零", 0L).set("〇", 0L).set("一", 1L).set("壹", 1L).set("二", 2L).set("贰", 2L)
                .set("三", 3L).set("叁", 3L).set("四", 4L).set("肆", 4L).set("五", 5L).set("伍", 5L).set("六", 6L)
                .set("陆", 6L).set("七", 7L).set("柒", 7L).set("八", 8L).set("捌", 8L).set("九", 9L).set("玖", 9L)
                .set("十", 10L).set("拾", 10L).set("百", 100L).set("佰", 100L).set("千", 1000L).set("仟", 1000L)
                .set("万", 10000L).set("萬", 10000L).set("亿", 100000000L).set("億", 100000000L).set("兆", 1000000000000L);
        /* 如果出现意料之外的字符,直接返回0 */
        if(ReUtil.findAll(StrUtil.format("[^{}负点]",baseUnitDict.keySet().stream().collect(Collectors.joining(""))), numStr, 0).size() > 0){
            return NumberUtil.toBigDecimal(0);
        }
        boolean minusFlag = false;
        if(numStr.startsWith("负")){
            minusFlag = true;
            numStr = numStr.substring(1);
        }
        //整数部分
        String integerStr = null;
        //小数部分
        String decimalStr = null;
        if (numStr.indexOf('点') == -1) {
            integerStr = numStr;
            decimalStr = "";
        } else {
            String[] parts = numStr.split("点");
            integerStr = parts[0];
            decimalStr = parts[1];
        }
        String[] integerCharArr = integerStr.split("");
        /* 整数总计 */
        BigDecimal integerNum = new BigDecimal(0);
        /* 整数总计级别记录 */
        Long sumLevel = 0L;
        /* 分阶段合计 */
        BigDecimal subNum = new BigDecimal(0);
        /* 分阶段级别记录 */
        Long subLevel = 0L;
        /* 当前计算值 */
        BigDecimal calcNum = new BigDecimal(0);
        for(int x = 0; x < integerCharArr.length; x++){
            String charStr = integerCharArr[x];
            Long curVal = baseUnitDict.getLong(charStr);
            switch (charStr){
                case "十":
                case "拾":
                case "百":
                case "佰":
                case "千":
                case "仟":
                case "万":
                case "萬":
                case "亿":
                case "億":
                case "兆":
                    /* 处理计数单位前没有量词的特例,例如十一[十 拾前面没有具体的量词],按照语法特性,前面应为一 */
                    if(("十".equals(charStr) || "拾".equals(charStr)) && NumberUtil.equals(NumberUtil.toBigDecimal(0), calcNum)){
                        calcNum = NumberUtil.toBigDecimal(1);
                    }
                    if(curVal >= sumLevel){
                        /* 如果当前的计数单位级别 大于等于 总计计数单位级别, 则将总计与所有下阶计数相加,再与当前计数单位级别数值相乘,除总计外其他计数归零 */
                        subLevel = 0L;
                        sumLevel = curVal;
                        subNum = subNum.add(calcNum);
                        integerNum = integerNum.add(subNum).multiply(NumberUtil.toBigDecimal(curVal));
                        subNum = subNum.multiply(NumberUtil.toBigDecimal(0));
                    } else{
                        if(curVal >= subLevel){
                            subLevel = curVal;
                            subNum = subNum.add(calcNum).multiply(NumberUtil.toBigDecimal(curVal));
                        } else{
                            subNum = subNum.add(calcNum.multiply(NumberUtil.toBigDecimal(curVal)));
                        }
                    }
                    calcNum = calcNum.multiply(NumberUtil.toBigDecimal(0));
                    break;
                default:
                    calcNum = calcNum.add(NumberUtil.toBigDecimal(curVal));
                    break;
            }
            /* 处理完最后一个字符, 将剩余的计数相加 */
            if(x < (integerCharArr.length - 1)){
                continue;
            }
            integerNum = integerNum.add(subNum.add(calcNum));
        }
        /* 小数总计 */
        BigDecimal decimalNum = new BigDecimal(0);
        String[] decimalCharArr = decimalStr.split("");
        for(int x = 0; x < decimalCharArr.length; x++){
            String charStr = decimalCharArr[x];
            Long curVal = baseUnitDict.getLong(charStr);
            decimalNum = decimalNum.add(NumberUtil.toBigDecimal(curVal).divide(NumberUtil.toBigDecimal(10).pow(x+1)));
        }
        return new BigDecimal(0).add(integerNum).add(decimalNum).multiply(NumberUtil.toBigDecimal(minusFlag?-1:1));
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值