輸入:金額的中文大寫(xiě)(字符串)
輸出:阿拉伯?dāng)?shù)字(float或int型)
????整數(shù)部分主要是利用正則表達(dá)式進(jìn)行檢索,將對(duì)應(yīng)項(xiàng)的數(shù)字與單位列表的對(duì)應(yīng)項(xiàng)相乘并求和,小數(shù)部分也是一樣的手法,但是由于可能存在只有角的情況,正則表達(dá)式不好處理,而且角、分這里涉及的情況并不多,所以我們分離處理
1. 初始化參數(shù)
def __init__(self, word):
"""
:param word: 用戶傳入的中文字符串
初始化參數(shù),包括:
{
is_int :int/float 是否為純整數(shù)
word:str 用作轉(zhuǎn)換的中文金額
int_part:str 整數(shù)部分字符串
dec_part:str 小數(shù)部分字符串
int_level:list 整數(shù)部分的單位列表
trans_tab:dict 映射表
pattern:_sre.SRE_Pattern 正則表達(dá)式compile規(guī)則
}
"""
if word.endswith('圓'):
self.int_part = word
self.is_int = True
elif word.endswith('角') or word.endswith('分'):
self.int_part = word[:word.index('圓') + 1]
self.dec_part = word[word.index('圓') + 1:]
self.is_int = False
self.word = word
self.int_level = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000,
100000000000, 1000000000000]
self.trans_tab = str.maketrans('零壹貳叁肆伍陸柒捌玖', '0123456789')
self.pattern = re.compile('(?:(.*?)兆)?(?:(.*?)千)?(?:(.*?)百)?(?:(.*?)拾)?(?:(.*?)億)?(?:(.*?)千)?(?:(.*?)佰)'
'?(?:(.*?)拾)?(?:(.*?)萬(wàn))?(?:(.*?)仟)?(?:(.*?)佰)?(?:(.*?)拾)?(.*?)圓')
2. 處理整數(shù)部分
I. 用正則表達(dá)式按照模板檢索(從兆位到個(gè)位,沒(méi)有對(duì)應(yīng)項(xiàng)則為空)
II. 按照映射表執(zhí)行映射后組合成數(shù)字列表
III. 將數(shù)字列表與數(shù)字單位列表的對(duì)應(yīng)索引項(xiàng)進(jìn)行相乘后求和
# 用正則表達(dá)式按照模板檢索(從兆位到個(gè)位,沒(méi)有對(duì)應(yīng)項(xiàng)則為空)
word_list = re.findall(self.pattern, self.int_part)[0]
# 按照映射表執(zhí)行映射后組合成數(shù)字列表
number_list = list(reversed(list(map(self.word_format, word_list))))
# 將數(shù)字列表與數(shù)字單位列表的對(duì)應(yīng)索引項(xiàng)進(jìn)行相乘后求和
print(sum(
[int(number_list[i]) * self.int_level[i] for i in range(len(number_list))]
))
3. 處理小數(shù)部分
I. 長(zhǎng)度為4:N角N分,獲取到角和分對(duì)應(yīng)的數(shù)字,映射后與單位相乘求和
if len(self.dec_part) == 4:
dec_word_list = list(self.dec_part[0] + self.dec_part[2])
dec_number_list = list(map(self.word_format, dec_word_list))
dec_number = int(dec_number_list[0]) * 0.1 + int(dec_number_list[1]) * 0.01
II. 長(zhǎng)度為3:零N分,獲取到分對(duì)應(yīng)的數(shù)字,執(zhí)行映射后與單位相乘
elif len(self.dec_part) == 3:
dec_number = int(self.word_format(self.dec_part[:-1])) * 0.01
III. 長(zhǎng)度為2,N角,獲取到角對(duì)應(yīng)的數(shù)字,執(zhí)行映射后與單位相乘
else:
dec_number = int(self.word_format(self.dec_part[:-1])) * 0.1
4. 數(shù)據(jù)映射
????和之前提到的映射方法一致,只是將數(shù)字與漢字對(duì)調(diào),這里有一個(gè)對(duì)字符串的處理,如果是
零N的形式則將字符串替換為N,如果是空字符串,則按照零執(zhí)行映射
def word_format(self, word):
"""
:param word: 對(duì)傳入的word字符串進(jìn)行映射處理
:return: 根據(jù)傳入字符串的長(zhǎng)度進(jìn)行處理后執(zhí)行映射
"""
if len(word) > 1:
return word[-1].translate(self.trans_tab)
elif len(word) == 0:
return '零'.translate(self.trans_tab)
return word.translate(self.trans_tab)
5. 數(shù)據(jù)檢查
判斷數(shù)據(jù)合理性
def data_check(self):
"""
數(shù)據(jù)檢查,是否符合輸入要求
:return: 傳入的數(shù)據(jù)不是字符串類(lèi)型或者長(zhǎng)度越界則返回False,否則返回True
"""
if not isinstance(self.word, str):
return False
if self.is_int:
if len(self.int_part) > 26:
return False
else:
return True
else:
if len(self.int_part) > 26 or len(self.dec_part) > 4:
return False
else:
return True

EUA2OADG6(QB.png