rmb_lower.py 3.18 KB
import re


class RMBHandler:

    def __init__(self):
        self.num_mapping = {
            '零': 0,
            '壹': 1,
            '贰': 2,
            '叁': 3,
            '肆': 4,
            '伍': 5,
            '陆': 6,
            '柒': 7,
            '捌': 8,
            '玖': 9
        }
        self.unit_mapping = {
            '厘': (0, 0.001),
            '分': (1, 0.01),
            '角': (2, 0.1),
            '圆': (3, 1),
            '拾': (4, 10),
            '佰': (5, 100),
            '仟': (6, 1000),
            '万': (7, 10000),
            '亿': (8, 100000000)
        }

    def upper_to_lower(self, price):
        result = 0
        last_unit_idx = 0
        num = 0
        for idx, c in enumerate(price):
            if c in self.num_mapping:
                num = self.num_mapping.get(c)
            else:
                if idx == 0:
                    num = 1
                unit_idx, unit = self.unit_mapping.get(c, (0, 0))
                if unit_idx > last_unit_idx:
                    result = (result + num) * unit
                else:
                    result = result + (num * unit)
                last_unit_idx = unit_idx
                num = 0
        return result

    def pre_process(self, price, upper=True):
        if upper:
            for idx, c in enumerate(price):
                if c in self.num_mapping or c in self.unit_mapping:
                    head = idx
                    break
            else:
                return None

            for idx in range(len(price)-1, -1, -1):
                if price[idx] in self.num_mapping or price[idx] in self.unit_mapping:
                    tail = idx + 1
                    break
            else:
                return None

            return price[head: tail]
        else:
            pass

    def to_rmb_lower(self, price):
        try:
            if re.search(r'[\d]', price) is None:
                price = self.pre_process(price)
                if not price:
                    return None
                result = self.upper_to_lower(price)
                if result is not None:
                    result = float(round(result, 3))
                return result
            else:
                re_obj = re.search(r'(\d+\.?\d*)([万亿]?)', price)
                digit = float(re_obj.group(1))
                unit = re_obj.group(2)
                if unit in self.unit_mapping:
                    digit = digit * self.unit_mapping[unit][1]
                return digit
        except Exception as e:
            return None


rmb_handler = RMBHandler()

if __name__ == '__main__':
    test_2 = ['壹万伍仟肆佰壹拾圆叁角伍分肆厘', '捌万陆仟肆佰壹拾圆整', '壹万伍仟肆佰壹拾元贰角捌分肆厘', '拾壹亿壹仟万伍仟肆佰壹拾元贰角捌分肆厘', '拾伍万圆']
    test_1 = ['sfdds', '柒佰玖拾万元整', '100万元整', '人民币伍佰万圆整', '人民币壹仟万元', '100万元', '贰佰壹拾捌万圆整', '(人民币)壹仟万元', '壹佰壹拾万圆整', '人民币30.0000万元整', '伍拾万元人民币', '200万']
    input_list = test_1
    for i in input_list:
        print('{0}={1}'.format(i, rmb_handler.to_rmb_lower(i)))