IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python 处理人民币金额,大小写互转 -> 正文阅读

[Python知识库]Python 处理人民币金额,大小写互转

在工作中经常可以遇到人民币金额大小写的转换问题,这里是以 Python3 实现的人民币大小写转换的脚本,实测可用,准确无误,最大支持16位以内的金额大小写转换。
脚本如下,可以在本地启动后输入小写金额进行验证:

# handleCNY.py

class ChangeCNY(object):
    NUM_DICT = {
        '0': '零',
        '1': '壹',
        '2': '贰',
        '3': '叁',
        '4': '肆',
        '5': '伍',
        '6': '陆',
        '7': '柒',
        '8': '捌',
        '9': '玖',
        '10': '拾',
        '100': '佰',
        '1000': '仟'
    }
    CN_TO_NUM = {item[1]: item[0] for item in NUM_DICT.items()}
    VALIDATE_CN = [item[1] for item in NUM_DICT.items()] + ['分', '角', '元', '拾', '佰', '仟', '万', '亿', '兆', '整']
    MIN_CN = ['角', '分']
    
    
    def validate(self, val, small=True):
        '''金额验证器
        args:
            val str:输入的金额
            small bool:小写金额为True,大写金额为False
        returns:
            str/tuple:返回一个验证后的字符串或列表,验证的是大写金额时返回字符串;否则返回小写金额元组(整数部分, 小数部分)
        '''
        err = ""
        if not isinstance(val, str):
            raise ValueError("传入的类型错误,期待一个字符串类型。")
        if small:
            target = val.split('.')
            if len(target) > 2:
                raise ValueError("传入的值错误,异常的小写金额。")
            if len(target[0]) > 16:
                raise ValueError("输入金额超限,无法计算。")
            if len(target) > 1 and len(target[1]) > 2:
                raise ValueError("传入的值错误,小数部分不能超过三位。")
            for item in target:
                if not item.isnumeric():
                    err = '传入的值错误,异常的小写金额。'
                    break
            if err:
                raise ValueError(err)
            res = (target[0], target[1]) if len(target) > 1 else (target[0], 0)
            return res
        for s in val:
            if s not in self.VALIDATE_CN:
                err = '传入的值错误,异常的大写金额。'
        if err:
            raise ValueError(err)
        return val


    def small_to_big(self, small):
        '''将小写金额转换成大写金额的方法
        args:
            small str:接收一个小写金额字符串
        returns:
            str:返回一个大写的人民币金额
        '''
        max, min = self.validate(val=small)
        # 处理小数部分
        if min:
            min_str = ''
            for index, num in enumerate(min):
                min_str += '%s%s' % (self.NUM_DICT[num], self.MIN_CN[index])
        else:
            min_str = '整'
        # 处理整数部分
        big_str = ''
        change_swap = ['', '拾', '佰', '仟']
        unit_swap = ['元', '万', '亿', '兆']
        for index, num in enumerate(max[::-1]):
            if index%4 == 0:
                change_swap[0] = unit_swap[index//4]
                # 如果刚好关键位为0,那就是不给零,只给标志位
                if num == '0':
                    big_str += change_swap[index%4]
                    continue
                big_str += '%s%s' % (change_swap[index%4], self.NUM_DICT[num])
            else:
                if num == '0':
                    big_str += self.NUM_DICT[num]
                    continue
                big_str += '%s%s' % (change_swap[index%4], self.NUM_DICT[num])
        # 去掉多于的零
        big_str = big_str[::-1]
        # print(big_str)
        tmp_str = ''
        for i in range(len(big_str)):
            if i == len(big_str):
                continue
            if big_str[i] == '零' and big_str[i+1] == '零':
                continue
            if big_str[i] == '零' and big_str[i+1] in unit_swap:
                continue
            tmp_str += big_str[i]
        # 整合整数部分和小数部分返回
        return tmp_str + min_str
    
    def __call_handle_big(self, big_str):
        '''一个用于处理整数大写金额的递归函数
        args:
            big_str str:接收一个大写的整数金额
        returns:
            str:返回一个小写的金额字符串
        '''
        min_ls = []
        max_unit = ''
        unit_swap = {'元': 1, '万': 5, '亿': 9, '兆': 13}
        for s in unit_swap:
            if s in big_str:
                if len(min_ls) < unit_swap[s]:
                    min_ls = ['' for _ in range(unit_swap[s])]
                    max_unit = s
        if len(big_str.split(max_unit)) > 1:
            front, back = big_str.split(max_unit)[0], big_str.split(max_unit)[1]
        else:
            front, back = big_str.split(max_unit)[0], []
        tmp_ls = []
        inner_ls = []
        for cn in front:
            if cn != '零':
                inner_ls.append(self.CN_TO_NUM[cn])
            else:
                tmp_ls.append(inner_ls)
                inner_ls = []
        tmp_ls.append(inner_ls)
        all_tp = 0
        for need_calc in tmp_ls:
            tp = 0
            for i in range(len(need_calc)):
                # 是最后一个数据,并且是奇数的时候
                if i+1 == len(need_calc) and (i+1) % 2 != 0:
                    tp += int(need_calc[i]) 
                if (i+1) % 2 == 0:
                    tp += int(need_calc[i]) * int(need_calc[i-1])
            all_tp += tp
        all_tp = str(all_tp)
        if len(all_tp) != 4:
            all_tp = ('0'*(4-len(all_tp))) + all_tp
        if not back:
            return all_tp
        else:
            return all_tp + self.__call_handle_big(back)
        
    def big_to_small(self, big):
        '''将大写金额转为小写金额的方法
        args:
            big str:接收一个大写金额字符串,支持有小数的金额
        returns:
            str:返回一个小写金额字符串
        '''
        big_str = self.validate(big, small=False)
        # 初始化小数和整数部分
        dec = ''
        get_int = ''
        if '整' in big_str:
            get_int = self.__call_handle_big(big_str[:-1])
        else:
            # 处理小数部分
            if big_str[-1] == '分':
                dec = '.%s%s' % (self.CN_TO_NUM[big_str[-4]], self.CN_TO_NUM[big_str[-2]])
                get_int = self.__call_handle_big(big_str[:-4])
            else:
                dec = '.%s' % (self.CN_TO_NUM[big_str[-2]])
                get_int = self.__call_handle_big(big_str[:-2])
        # 去掉整数前面多于的零
        remove_index = 0
        for s in get_int:
            if s != '0':
                break
            remove_index += 1
        res_small = get_int[remove_index:] + dec
        return res_small
                    
            
            
            
        
if __name__ == '__main__':
    change = ChangeCNY()
    while 1:
        small = input('请输入小写金额(退出请输入q):')
        if small == 'q':
            print('Bye...')
            break
        print(f'输入的金额:{small}')
        print(f'大写金额为:{change.small_to_big(small)}')
        print(f'再次变换为:{change.big_to_small(change.small_to_big(small))}')

执行:

python handleCNY.py
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-12-08 13:46:09  更:2021-12-08 13:48:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 6:01:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码