中文大寫(xiě)轉(zhuǎn)阿拉伯?dāng)?shù)字(金額)


輸入:金額的中文大寫(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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容