汉字数字转换为阿拉伯数字

场景:工作中需要把数字、汉字、数字汉字混合的数转换为数字型。待转换的包括但不限于以下类型:”四十万零五百”,”四千八百三”, “零”, “4331”, “4百万”, “4万”, “百万”, “百”, “3万4”, “3万四”, “三万四”, “三万4”
我一开始用从前往后挨个转换,总是存在局限和问题。查找了网上的方法,大多数都是从后往前,挨着来,然后乘以单位之类的。
我想到个办法,可不跟网上那些妖艳的贱货一样。
我的暂时就叫补全法
其实仔细分析,相对于单位来说,待转换的都是简略写法,转换后的数字都是补全的写法,哪怕是零也会补全。比如说三万四,这个数字缺少了单位“千”,缺少了个十百位;但是数字“34000”就一个不少。可以总结为以下四种情况:
根据以上的情况分析,“四万零八百三”可以这样分析:
大体思路如上,具体的思路和伪码以及注释,见下面的代码:
import re


def transfer(amount: str) -> str:
    """
    amount: 提取到的价格的详细数字 例如:4百(万) 百(万) 千(万)
    将amount标准化为:4百(万)->400(万)
    """
    # 四百三十万
    unit_list = ["兆", "千亿", "百亿", "十亿", "亿", "千万", "百万", "十万", "万", "千", "百", "十", "个"]
    transfer_list = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]
    real_amount = 0

    if re.findall("^\d{1,}$", amount):
        return amount

    amount_unit_index = -1
    unit_list_index = -1
    # 找到单位列表中的起始位置,即找到数字的最大单位
    for index in range(0, len(amount)):
        if amount[index:index + 2] in unit_list:
            amount_unit_index = index
            unit_list_index = unit_list.index(amount[index:index + 2])
            break
        elif amount[index] in unit_list:
            amount_unit_index = index
            unit_list_index = unit_list.index(amount[index])
            break

    # 数字字符串下标从头开始
    amount_unit_index = 0
    amount_result = ""
    # 按照单位列表的顺序找,即按照单位从大到小的顺序提取数量
    for index in range(unit_list_index, len(unit_list)):
        # 如果当前单位在数字字符串中,那么从上次单位结束的位置开始查找和抽取
        if unit_list[index] in amount[amount_unit_index::]:
            result = re.findall("(.*?)" + unit_list[index], amount[amount_unit_index::])
            if result[0] != '':  # 抽到单位前面的数字了
                print(result[0], unit_list[index], end="\t")
                amount_result += result[0]
            else:  # 没抽到单位前面的数字但是单位确实存在,默认为一,比如我告诉你百万,默认是一百万
                print('一', unit_list[index], end="\t")
                amount_result += '一'
            amount_unit_index += (len(unit_list[index]) + 1)
            continue
        # 如果单位不在数字字符串中,但是数量可能存在,例如八百三,这里的三就没有单位,但是可以依据三前面的单位提取
        result = re.findall(unit_list[index - 1] + "(.)", amount[amount_unit_index - 1::])
        if len(result) > 0:
            print(result, unit_list[index], end="\t")
            amount_result += result[0]
            amount_unit_index += 1
            continue
        # 上面两种情况都不存在 那就当前单位补零
        print("零", unit_list[index], end="\t")
        amount_result += "零"
    # 将汉字替换为数字 四百->400
    for index in range(0, len(transfer_list)):
        amount_result = amount_result.replace(transfer_list[index], str(index))
    return str(int(amount_result))


if __name__ == '__main__':
    price_list = ["四十万零五百", "四千八百三", "零", "4331", "4百万", "4万", "百万", "百", "3万4", "3万四", "三万四", "三万4"]
    result = []
    for item in price_list:
        result = transfer(item)
        print('->', result)
        print("")
测试运行结果:

四 十万 零 万 [‘零’] 千 五 百 零 十 零 个 -> 400500四 十万 零 万 [‘零’] 千 五 百 零 十 零 个 -> 400500
四 千 八 百 [‘三’] 十 零 个 -> 4830
零 个 零 兆 零 千亿 零 百亿 零 十亿 零 亿 零 千万 零 百万 零 十万 零 万 零 千 零 百 零 十 零 个 -> 0
-> 4331
4 百万 零 十万 零 万 零 千 零 百 零 十 零 个 -> 4000000
4 万 零 千 零 百 零 十 零 个 -> 40000
一 百万 零 十万 零 万 零 千 零 百 零 十 零 个 -> 1000000
一 百 零 十 零 个 -> 100
3 万 [‘4’] 千 零 百 零 十 零 个 -> 34000
3 万 [‘四’] 千 零 百 零 十 零 个 -> 34000
三 万 [‘四’] 千 零 百 零 十 零 个 -> 34000
三 万 [‘4’] 千 零 百 零 十 零 个 -> 34000

Process finished with exit code 0

发表评论

电子邮件地址不会被公开。 必填项已用*标注