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)))