金额转换
很多情况下需要对文本当中的金额进行抽取转储成数值,往往又存在诸多恶心的不规范标记/表述/或者原始数据获取残缺的情况,因此做记录。
思路
实际上,字符串转换到数值,最大的麻烦十进制表示关系不如阿拉伯数字直观,自然语言的表述是嵌套甚至是省略的。但是有一点可以确定的是,自然语言对金额/数字的表述,也是存在逻辑关系的。比如:九百六十万九仟八百一。从字面上看,同样表述几百几千,会在多个位置出现,所以肯定是不能用正则或者其他纯字符传组织形式的方法去推敲转换。
但是,不难发现,作为自然语言,表述尽管错乱多样,但是内部本身逻辑是十分紧密的:比如,最前面九百六十修饰的是单位“万”,末尾的九千八百最作为“万”下级单位的补充 – 因此是不是可以考虑将字符串按照当前最大单位进行拆分,二分成当前进制跟补充零头求和,再分别对拆分出来的子字符串进行递归拆分,最后计算出总和。
代码
# Author: Bao Jx
import re
def string_to_yuan(string, base_unit='y', right_side=False):
"""
Convert the traditional expression of price to the numerical
value in the measurement unit of yuan.
e.g.
>> a = '4佰零七万9仟一百26元'
b = '409万八千零71'
c = '23万6.2千503'
d = '23.1千802元'
<< 4079126.0
4098071.0
236703.0
23902.0
>> %timeit string_to_yuan('一百1拾九万3千零2拾3亿83.2万零三')
<< 280 µs ± 14.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
:param string: traditional expression of price
:param base_unit:
:param right_side:
:return: numerical data
"""
def normal(string):
string = re.sub('億', '亿', string)
string = re.sub('萬', '万', string)
string = re.sub('仟', '千', string)
string = re.sub('佰', '百', string)
string = re.sub(