Python實(shí)現(xiàn)將中文大寫金額轉(zhuǎn)數(shù)字金額
在日常的財(cái)務(wù)處理、票據(jù)識(shí)別或金融系統(tǒng)開發(fā)中,我們常常需要將中文大寫的金額轉(zhuǎn)換為阿拉伯?dāng)?shù)字形式。例如:
- “壹佰元整” → “100”
- “壹仟貳佰叁拾肆元伍角陸分” → “1234.56”
- “壹拾陸萬(wàn)元” → “160000”
這類需求在銀行票據(jù)OCR識(shí)別、合同金額處理等場(chǎng)景中非常常見(jiàn)。本文將詳細(xì)介紹如何使用 Python 編寫一個(gè)能夠準(zhǔn)確識(shí)別并轉(zhuǎn)換中文大寫金額的函數(shù),并通過(guò)對(duì)比驗(yàn)證其準(zhǔn)確性。
一、中文大寫金額規(guī)則簡(jiǎn)介
中文大寫金額由以下部分組成:
數(shù)字部分(0~9):
零 壹 貳 叁 肆 伍 陸 柒 捌 玖
單位部分:
拾 佰 仟 萬(wàn) 億
小數(shù)單位:
角 分
特殊標(biāo)記:
- “元”:整數(shù)部分結(jié)束標(biāo)志
- “整”:表示無(wú)角分
- “零”:表示中間有空位
二、Python 實(shí)現(xiàn)思路解析
1. 映射關(guān)系定義
我們首先定義兩個(gè)字典,分別用于映射中文數(shù)字和單位到對(duì)應(yīng)的數(shù)值:
num_map = {
'零': 0, '壹': 1, '貳': 2, '叁': 3, '肆': 4,
'伍': 5, '陸': 6, '柒': 7, '捌': 8, '玖': 9
}
unit_map = {
'拾': 10, '佰': 100, '仟': 1000,
'萬(wàn)': 10000, '億': 100000000
}
2. 預(yù)處理輸入字符串
去除多余的空格與“整”字,便于后續(xù)解析:
capital = capital.replace(' ', '').replace('整', '')
3. 分離整數(shù)與小數(shù)部分
根據(jù)“元”分割出整數(shù)部分與角分部分:
if '元' in capital:
parts = capital.split('元')
yuan_part = parts[0]
jiao_fen_part = parts[1] if len(parts) > 1 else ''
else:
yuan_part = capital
4. 解析整數(shù)部分
核心邏輯是逐字符遍歷,遇到數(shù)字則記錄臨時(shí)值,遇到單位則進(jìn)行乘法運(yùn)算:
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
5. 處理“億”和“萬(wàn)”的層級(jí)結(jié)構(gòu)
遞歸處理“億”和“萬(wàn)”的分層結(jié)構(gòu):
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 '萬(wàn)' in s:
parts = s.split('萬(wàn)')
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)
6. 角分處理
處理角分部分,支持“角”、“分”、“角分”三種組合:
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,
'萬(wàn)': 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 '萬(wàn)' in s:
parts = s.split('萬(wàn)')
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))
四、測(cè)試驗(yàn)證
我們可以編寫一個(gè)簡(jiǎn)單的對(duì)比函數(shù)來(lái)驗(yàn)證轉(zhuǎn)換結(jié)果是否正確:
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" 轉(zhuǎn)換結(jié)果: {capital_to_small}")
return False
except Exception as e:
print(f"轉(zhuǎn)換出錯(cuò): {e}")
return False
運(yùn)行測(cè)試:
get_dx_compare('壹拾陸萬(wàn)元', '160000') # ? 應(yīng)該輸出匹配
get_dx_compare('壹萬(wàn)元', '10000')
get_dx_compare('零元整', '0')
get_dx_compare('壹佰元整', '100')
get_dx_compare('壹仟貳佰叁拾肆元伍角陸分', '1234.56')
輸出結(jié)果如下:
? 金額匹配:小寫金額 160000元,大寫金額 壹拾陸萬(wàn)元
? 金額匹配:小寫金額 10000元,大寫金額 壹萬(wàn)元
? 金額匹配:小寫金額 0元,大寫金額 零元整
? 金額匹配:小寫金額 100元,大寫金額 壹佰元整
? 金額匹配:小寫金額 1234.56元,大寫金額 壹仟貳佰叁拾肆元伍角陸分
五、總結(jié)
本文提供了一個(gè)較為完整的中文大寫金額轉(zhuǎn)阿拉伯?dāng)?shù)字的 Python 實(shí)現(xiàn)方案,涵蓋以下關(guān)鍵點(diǎn):
- 數(shù)字與單位映射
- 整數(shù)部分層級(jí)解析(億、萬(wàn)、千、百、十)
- 角分部分精確處理
- 輸入預(yù)處理(去空格、去“整”)
- 結(jié)果驗(yàn)證機(jī)制
你可以將其用于金融系統(tǒng)中的金額校驗(yàn)、OCR識(shí)別后處理、合同文本解析等場(chǎng)景。
以上就是Python實(shí)現(xiàn)將中文大寫金額轉(zhuǎn)數(shù)字金額的詳細(xì)內(nèi)容,更多關(guān)于Python金額大寫轉(zhuǎn)數(shù)字的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在pycharm中輸入import torch報(bào)錯(cuò)如何解決
這篇文章主要介紹了在pycharm中輸入import torch報(bào)錯(cuò)如何解決問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
Python二進(jìn)制串轉(zhuǎn)換為通用字符串的方法
今天小編就為大家分享一篇Python二進(jìn)制串轉(zhuǎn)換為通用字符串的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
原來(lái)我一直安裝 Python 庫(kù)的姿勢(shì)都不對(duì)呀
平常我都是直接執(zhí)行 pip install 安裝的第三方庫(kù),很多教程也是這么介紹的,一直以來(lái)我都認(rèn)為這是標(biāo)準(zhǔn)的、正確的安裝 Python 第三方庫(kù)的姿勢(shì)。下面小編給大家分享一篇教程,一起看看吧2019-11-11
Python自動(dòng)化實(shí)現(xiàn)日?qǐng)?bào)數(shù)據(jù)可視化
這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)自動(dòng)化生成日?qǐng)?bào)數(shù)據(jù)可視化,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02
Python中用altzone()方法處理時(shí)區(qū)的教程
這篇文章主要介紹了Python中用altzone()方法處理時(shí)區(qū)的教程,是Python入門中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-05-05
python實(shí)現(xiàn)大戰(zhàn)外星人小游戲?qū)嵗a
這篇文章主要介紹了python實(shí)現(xiàn)大戰(zhàn)外星人小游戲,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12

