文章目录
- 我们首先定义两个字典,分别用于映射中文数字和单位到对应的数值: num_map = { ‘零’: 0, ‘壹’: 1, ‘贰’: 2, ‘叁’: 3, ‘肆’: 4, ‘伍’: 5, ‘陆’: 6, ‘柒’: 7, ‘捌’: 8, ‘玖’: 9 } unit_map = { ‘拾’: 10, ‘佰’: 100, ‘仟’: 1000, ‘万’: 10000, ‘亿’: 100000000 }
- 去除多余的空格与“整”字,便于后续解析: capital = capital.replace(‘ ‘, ”).replace(‘整’, ”)
- 根据“元”分割出整数部分与角分部分: if ‘元’ in capital: parts = capital.split(‘元’) yuan_part = parts[0] jiao_fen_part = parts[1] if len(parts) > 1 else ” else: yuan_part = capital
- 核心逻辑是逐字符遍历,遇到数字则记录临时值,遇到单位则进行乘法运算: def parse_section(s): if not s: return 0 if s == ‘拾’: # 特殊情况:”拾”表示10 return 10 result = 0 temp = 0 for char in s: if char in num_map: temp = num_map[char] elif char in unit_map: result += temp * unit_map[char] temp = 0 result += temp return result
- 递归处理“亿”和“万”的分层结构: def parse_amount(s): if ‘亿’ in s: parts = s.split(‘亿’) yi_part = parts[0] rest_part = parts[1] if len(parts) > 1 else ” value = parse_section(yi_part) * 100000000 if rest_part: value += parse_amount(rest_part) return value elif ‘万’ in s: parts = s.split(‘万’) wan_part = parts[0] rest_part = parts[1] if len(parts) > 1 else ” value = parse_section(wan_part) * 10000 if rest_part: value += parse_section(rest_part) return value else: return parse_section(s)
- 处理角分部分,支持“角”、“分”、“角分”三种组合: def parse_jiao_fen(jf): if not jf: return “” jiao = 0 fen = 0 if ‘角’ in jf and ‘分’ in jf: parts = jf.split(‘角’) if parts[0] in num_map: jiao = num_map[parts[0]] fen_part = parts[1].replace(‘分’, ”) if fen_part in num_map: fen = num_map[fen_part] elif ‘角’ in jf: jiao_part = jf.replace(‘角’, ”) if jiao_part in num_map: jiao = num_map[jiao_part] elif ‘分’ in jf: fen_part = jf.replace(‘分’, ”) if fen_part in num_map: fen = num_map[fen_part] if jiao > 0 and fen > 0: return f”.{jiao}{fen}” elif jiao > 0: return f”.{jiao}0″ elif fen > 0: return f”.0{fen}” else: return “”
目录
- 一、中文大写金额规则简介
- 二、Python 实现思路解析
- 1. 映射关系定义
- 2. 预处理输入字符串
- 3. 分离整数与小数部分
- 4. 解析整数部分
- 5. 处理“亿”和“万”的层级结构
- 6. 角分处理
- 三、完整代码示例
- 四、测试验证
- 五、总结
在日常的财务处理、票据识别或金融系统开发中,我们常常需要将中文大写的金额转换为阿拉伯数字形式。例如:
- “壹佰元整” → “100”
- “壹仟贰佰叁拾肆元伍角陆分” → “1234.56”
- “壹拾陆万元” → “160000”
这类需求在银行票据OCR识别、合同金额处理等场景中非常常见。本文将详细介绍如何使用 Python 编写一个能够准确识别并转换中文大写金额的函数,并通过对比验证其准确性。
中文大写金额由以下部分组成:
数字部分(0~9):
零 壹 贰 叁 肆 伍 陆 柒 捌 玖
单位部分:
拾 佰 仟 万 亿
小数单位:
角 分
特殊标记:
- “元”:整数部分结束标志
- “整”:表示无角分
- “零”:表示中间有空位
我们首先定义两个字典,分别用于映射中文数字和单位到对应的数值:
num_map = {
'零': 0, '壹': 1, '贰': 2, '叁': 3, '肆': 4,
'伍': 5, '陆': 6, '柒': 7, '捌': 8, '玖': 9
}
unit_map = {
'拾': 10, '佰': 100, '仟': 1000,
'万': 10000, '亿': 100000000
}
去除多余的空格与“整”字,便于后续解析:
capital = capital.replace(' ', '').replace('整', '')
根据“元”分割出整数部分与角分部分:
if '元' in capital:
parts = capital.split('元')
yuan_part = parts[0]
jiao_fen_part = parts[1] if len(parts) > 1 else ''
else:
yuan_part = capital
核心逻辑是逐字符遍历,遇到数字则记录临时值,遇到单位则进行乘法运算:
def parse_section(s):
if not s:
return 0
if s == '拾': # 特殊情况:"拾"表示10
return 10
result = 0
temp = 0
for char in s:
if char in num_map:
temp = num_map[char]
elif char in unit_map:
result += temp * unit_map[char]
temp = 0
result += temp
return result
递归处理“亿”和“万”的分层结构:
def parse_amount(s):
if '亿' in s:
parts = s.split('亿')
yi_part = parts[0]
rest_part = parts[1] if len(parts) > 1 else ''
value = parse_section(yi_part) * 100000000
if rest_part:
value += parse_amount(rest_part)
return value
elif '万' in s:
parts = s.split('万')
wan_part = parts[0]
rest_part = parts[1] if len(parts) > 1 else ''
value = parse_section(wan_part) * 10000
if rest_part:
value += parse_section(rest_part)
return value
else:
return parse_section(s)
处理角分部分,支持“角”、“分”、“角分”三种组合:
def parse_jiao_fen(jf):
if not jf:
return ""
jiao = 0
fen = 0
if '角' in jf and '分' in jf:
parts = jf.split('角')
if parts[0] in num_map:
jiao = num_map[parts[0]]
fen_part = parts[1].replace('分', '')
if fen_part in num_map:
fen = num_map[fen_part]
elif '角' in jf:
jiao_part = jf.replace('角', '')
if jiao_part in num_map:
jiao = num_map[jiao_part]
elif '分' in jf:
fen_part = jf.replace('分', '')
if fen_part in num_map:
fen = num_map[fen_part]
if jiao > 0 and fen > 0:
return f".{jiao}{fen}"
elif jiao > 0:
return f".{jiao}0"
elif fen > 0:
return f".0{fen}"
else:
return ""
def convert_capital_to_small(capital):
num_map = {
'零': 0, '壹': 1, '贰': 2, '叁': 3, '肆': 4,
'伍': 5, '陆': 6, '柒': 7, '捌': 8, '玖': 9
}
unit_map = {
'拾': 10, '佰': 100, '仟': 1000,
'万': 10000, '亿': 100000000
}
capital = capital.replace(' ', '').replace('整', '')
if not capital or capital == '零元':
return '0'
yuan_part = capital
jiao_fen_part = ''
if '元' in capital:
parts = capital.split('元')
yuan_part = parts[0]
if len(parts) > 1:
jiao_fen_part = parts[1]
else:
yuan_part = capital.replace('整', '')
def parse_section(s):
if not s:
return 0
if s == '拾':
return 10
result = 0
temp = 0
for char in s:
if char in num_map:
temp = num_map[char]
elif char in unit_map:
result += temp * unit_map[char]
temp = 0
result += temp
return result
def parse_amount(s):
if not s:
return 0
if len(s) == 1 and s in num_map:
return num_map[s]
if '亿' in s:
parts = s.split('亿')
yi_part = parts[0]
rest_part = parts[1] if len(parts) > 1 else ''
value = parse_section(yi_part) * 100000000
if rest_part:
value += parse_amount(rest_part)
return value
elif '万' in s:
parts = s.split('万')
wan_part = parts[0]
rest_part = parts[1] if len(parts) > 1 else ''
value = parse_section(wan_part) * 10000
if rest_part:
value += parse_section(rest_part)
return value
else:
return parse_section(s)
yuan_value = parse_amount(yuan_part)
def parse_jiao_fen(jf):
if not jf:
return ""
jiao = 0
fen = 0
if '角' in jf and '分' in jf:
parts = jf.split('角')
if parts[0] in num_map:
jiao = num_map[parts[0]]
fen_part = parts[1].replace('分', '')
if fen_part in num_map:
fen = num_map[fen_part]
elif '角' in jf:
jiao_part = jf.replace('角', '')
if jiao_part in num_map:
jiao = num_map[jiao_part]
elif '分' in jf:
fen_part = jf.replace('分', '')
if fen_part in num_map:
fen = num_map[fen_part]
if jiao > 0 and fen > 0:
return f".{jiao}{fen}"
elif jiao > 0:
return f".{jiao}0"
elif fen > 0:
return f".0{fen}"
else:
return ""
jf_str = parse_jiao_fen(jiao_fen_part)
if jf_str:
return f"{int(yuan_value)}{jf_str}"
else:
return str(int(yuan_value))
我们可以编写一个简单的对比函数来验证转换结果是否正确:
def get_dx_compare(capital_amount, small_amount):
try:
capital_to_small = convert_capital_to_small(capital_amount)
small_amount_clean = small_amount.replace(',', '')
converted_float = float(capital_to_small)
expected_float = float(small_amount_clean)
if converted_float == expected_float:
print(f"✓ 金额匹配:小写金额 {small_amount}元,大写金额 {capital_amount}")
return True
else:
print(f"✗ 金额不匹配:")
print(f" 小写金额: {small_amount}")
print(f" 大写金额: {capital_amount}")
print(f" 转换结果: {capital_to_small}")
return False
except Exception as e:
print(f"转换出错: {e}")
return False
运行测试:
get_dx_compare('壹拾陆万元', '160000') # ✅ 应该输出匹配
get_dx_compare('壹万元', '10000')
get_dx_compare('零元整', '0')
get_dx_compare('壹佰元整', '100')
get_dx_compare('壹仟贰佰叁拾肆元伍角陆分', '1234.56')
输出结果如下:
✓ 金额匹配:小写金额 160000元,大写金额 壹拾陆万元
✓ 金额匹配:小写金额 10000元,大写金额 壹万元
✓ 金额匹配:小写金额 0元,大写金额 零元整
✓ 金额匹配:小写金额 100元,大写金额 壹佰元整
✓ 金额匹配:小写金额 1234.56元,大写金额 壹仟贰佰叁拾肆元伍角陆分
本文提供了一个较为完整的中文大写金额转阿拉伯数字的 Python 实现方案,涵盖以下关键点:
- 数字与单位映射
- 整数部分层级解析(亿、万、千、百、十)
- 角分部分精确处理
- 输入预处理(去空格、去“整”)
- 结果验证机制
你可以将其用于金融系统中的金额校验、OCR识别后处理、合同文本解析等场景。
以上就是Python实现将中文大写金额转数字金额的详细内容,更多关于Python金额大写转数字的资料请关注风君子博客其它相关文章!
您可能感兴趣的文章:
- Python+PyQt编写一个数字转大写金额GUI工具
- Python实现中文大写金额转阿拉伯数字
- Python实现数字小写转大写的示例详解
- python2.x实现人民币转大写人民币
- python实现人民币大写转换
- python将人民币转换大写的脚本代码