何以
如果世界上曾经有那个人出现过,其他人都会变成将就...

1、单位和金额映射。

  • 单位数组添加的顺序需要按从大到小排序;
  • 支持错别字,只需要添加到列表元素Entry的值数组中;
  • 拾即是单位也是金额(比如壹拾元整,此时拾是单位;拾元整,此时拾是金额)
   /** 计量单位映射,按从大到小的顺序。 **/
    private static List<Entry<String, String[]>> units = new ArrayList<>();

    /** 金额数字映射。 **/
    private static List<Entry<String, String[]>> numbers = new ArrayList<>();

    static {
        units.add(new SimpleEntry<>("100000000", new String[] { "亿" }));
        units.add(new SimpleEntry<>("10000", new String[] { "万" }));
        units.add(new SimpleEntry<>("1000", new String[] { "仟" }));
        units.add(new SimpleEntry<>("100", new String[] { "佰" }));
        units.add(new SimpleEntry<>("10", new String[] { "拾" }));
        units.add(new SimpleEntry<>("1", new String[] { "圆" }));
        units.add(new SimpleEntry<>("0.1", new String[] { "角" }));
        units.add(new SimpleEntry<>("0.01", new String[] { "分" }));

        numbers.add(new SimpleEntry<>("0", new String[] { "零" }));
        numbers.add(new SimpleEntry<>("1", new String[] { "壹" }));
        numbers.add(new SimpleEntry<>("2", new String[] { "贰" }));
        numbers.add(new SimpleEntry<>("3", new String[] { "叁" }));
        numbers.add(new SimpleEntry<>("4", new String[] { "肆" }));
        numbers.add(new SimpleEntry<>("5", new String[] { "伍" }));
        numbers.add(new SimpleEntry<>("6", new String[] { "陆" }));
        numbers.add(new SimpleEntry<>("7", new String[] { "柒" }));
        numbers.add(new SimpleEntry<>("8", new String[] { "捌" }));
        numbers.add(new SimpleEntry<>("9", new String[] { "玖" }));
        numbers.add(new SimpleEntry<>("10", new String[] { "拾" }));
    }

2、大写转数字。

  • 按单位从大到小一部分一部分计算,例如捌仟捌佰捌拾捌万捌仟捌佰捌拾捌元整,捌仟捌佰捌拾捌万是一部分,捌仟、捌佰、捌拾、捌元分别为一部分。
  • 递归计算。如果有单位,规则为(递归计算金额)*单位;无单位,直接转成数字。
   /**
     * 大写金额转成数字。
     * 
     * @param chars 大写金额
     */
    private BigDecimal capitalizeToNumber(String chars) {
        if (StringUtils.isBlank(chars)) {
            return null;
        }

        int beginIndex = 0; // 未转换成数字的字符串位置
        BigDecimal summation = BigDecimal.ZERO;
        // 有计量单位的字符串转换成【数字 * 计量单位】
        for (Entry<String, String[]> unit : units) {
            String[] unitChars = unit.getValue();
            String matchChars = chars.substring(beginIndex);
            // 当前计量单位内待转换部分的位置
            int endIndex = StringUtils.indexOfAny(matchChars, unitChars);
            if (endIndex != -1) {
                // 取得当前计量单位内待转换的部分
                String segment = matchChars.substring(0, endIndex);
                // 待转换部分转换后的值,即被乘数
                BigDecimal multiplicand = capitalizeToNumber(segment);
                // 计量单位值,即乘数
                BigDecimal multiplier = new BigDecimal(unit.getKey());
                if (multiplicand != null && multiplier != null) {
                    summation = summation.add(multiplier.multiply(multiplicand));
                    // 此部分转换完成后,重新设置未转换部分的位置
                    beginIndex += (endIndex + 1);
                }
            }
        }
        // 无计量单位的转换成【数字】
        String numberChars = "";
        for (int i = beginIndex; i < chars.length(); i++) {
            String chr = String.valueOf(chars.charAt(i));
            for (Entry<String, String[]> number : numbers) {
                if (StringUtils.containsAny(chr, number.getValue())) {
                    numberChars += number.getKey();
                    break;
                }

            }
        }
        if (StringUtils.isNotBlank(numberChars)) {
            numberChars = numberChars.replaceAll("^(0*)([1-9]+)$", "$2"); // 剔除左边多余的0
            summation = summation.add(new BigDecimal(numberChars));
        }
        return summation;
    }

 

posted on 2021-11-01 14:30  Christing  阅读(1324)  评论(0)    收藏  举报