python阿拉伯数字转中文_阿拉伯数字转化为中文数字

# -*- coding:utf-8 -*-

'''中文财务数字转换程序.例如11111,可转换为:壹万壹仟壹佰壹拾壹"万仟佰拾"就是"单位","壹"就是"数值"'''

"""由于未涉及小数的处理,这里直接补上"""

flag = 0 #默认使用大写,如需使用小写,改成1即可

import re

unitArab=(2,3,4,5,9)

unitStr=u'十百千万亿' if flag else u'拾佰仟万亿'

#单位字典unitDic,例如(2,'十')表示给定的字符是两位数,那么返回的结果里面定会包含'十'.3,4,5,9以此类推.

unitDic=dict(zip(unitArab,unitStr))

numArab=u'0123456789'

numStr=u'零一二三四五六七八九' if flag else u'零壹贰叁肆伍陆柒捌玖'

#数值字典numDic,和阿拉伯数字是简单的一一对应关系

numDic=dict(zip(numArab,numStr))

yuan_dic = {0:"圆",1:"元"}

class Arab2chz(object):

def __init__(self,s):

self.__s =s #原始数值

@classmethod

def __wrapper(cls,v) -> str:

'''在口头表达中,针对整数部分多位连续0的简写规则设计的函数例如"壹佰零零"会变为"壹佰","壹仟零零壹"会变为"壹仟零壹"这里使用classmethod的意义在于本函数与对象无关系,不需要传入对象;下同'''

if u'零零' in v:

return Arab2chz.__wrapper(v.replace(u'零零', u'零'))

return v[:-1] if v[-1] == u'零' else v # 如果最后一位为0也应该去除'

@classmethod

def __recur(cls,s,bit)->str:

'''此函数接收2个参数:1.纯数字字符串2.此字符串的长度,相当于位数'''

#如果是一位数,则直接按numDic返回对应汉字

if bit==1:

return numDic[s]

#否则,且第一个字符是0,那么省略"单位"字符,返回"零"和剩余字符的递归字符串

if s[0]==u'0':

return Arab2chz.__wrapper(u'%s%s' % (u'零',Arab2chz.__recur(s[1:],bit-1)))

#否则,如果是2,3,4,5,9位数,那么返回最高位数的字符串"数值"+"单位"+"剩余字符的递归字符串"

if bit<6 or bit==9:

return Arab2chz.__wrapper(u'%s%s%s' % (numDic[s[0]],unitDic[bit],Arab2chz.__recur(s[1:],bit-1)))

#否则,如果是6,7,8位数,那么用"万"将字符串从万位数划分为2个部分.

#例如123456就变成:12+"万"+3456,再对两个部分进行递归.

if bit<9:

return u'%s%s%s' % (Arab2chz.__recur(s[:-4],bit-4),u"万",Arab2chz.__recur(s[-4:],4))

#否则(即10位数及以上),用"亿"仿照上面的做法进行划分.

if bit>9:

return u'%s%s%s' % (Arab2chz.__recur(s[:-8],bit-8),u"亿",Arab2chz.__recur(s[-8:],8))

@classmethod

def __deal_f(cls,s,dig:int)->str:

"""param dig: 保留小数点后面的位数"""

tar=""

if dig==0:

return tar

else:

tar+="点"

for e in s:

tar+=numDic[e]

return tar

def to_ora(self,dig:int =0)->str:

"""口头表达数字"""

s = str(round(float(self.__s),dig))

if "." in self.__s and dig!=0:

self.i,self.f = s.split(".")

else:

self.i, self.f = self.__s, "" #原本为整数

pattern = re.compile("零*$") # 去除末尾多余的零

pre = Arab2chz.__deal_f(self.f,dig)

pre_rem_ze = pattern.sub("",pre)

final = pre_rem_ze if not pre_rem_ze.endswith("点") else pre_rem_ze[:-1]

return Arab2chz.__recur(self.i,len(self.i)) + final

def to_money(self,dig:int = 2)->str:

""""加入货币单位"""

s = str(round(float(self.__s), dig)) #

if "." in s and dig != 0:

self.i, self.f= s.split(".") #整数、小数

if len(self.f) < dig:

self.f += self.f + "0"*(dig-len(self.f)) #补上0

else:

self.i,self.f = self.__s,"0" * dig #此时__s本身为整数

tar = ""

s_chz = "角分"

for i in range(dig):

tar += numDic[self.f[i]] + s_chz[i]

return Arab2chz.__recur(self.i, len(self.i)) +yuan_dic[flag] + tar +"整"

def to_print(self):

"""剔除小数点,根据字符串直接打印数字"""

return "".join([numDic(i) for i in self.__s.sub("",".")])

if __name__=="__main__":

for i in range(10):

v1='9'+'0'*(i+1)

v2='9'+'0'*i+'9'

print ('%s->%s\n%s->%s'% (v1,Arab2chz(v1).to_money(),

v2,Arab2chz(v2).to_money(0)))

print('%s->%s\n%s->%s' % (v1, Arab2chz(v1).to_ora(0),

v2,Arab2chz(v2).to_ora()))

print ("566949.58648 -->",Arab2chz("566949.58648").to_money(2),"\n",

"566949.58648 -->",Arab2chz("566949.58648").to_ora(2))

print("--"*20)

-----------------结果-----------

90->玖拾圆零角零分整

99->玖拾玖圆整

90->玖拾

99->玖拾玖

900->玖佰圆零角零分整

909->玖佰零玖圆整

900->玖佰

909->玖佰零玖

9000->玖仟圆零角零分整

9009->玖仟零玖圆整

9000->玖仟

9009->玖仟零玖

90000->玖万圆零角零分整

90009->玖万零玖圆整

90000->玖万

90009->玖万零玖

900000->玖拾万圆零角零分整

900009->玖拾万零玖圆整

900000->玖拾万

900009->玖拾万零玖

9000000->玖佰万圆零角零分整

9000009->玖佰万零玖圆整

9000000->玖佰万

9000009->玖佰万零玖

90000000->玖仟万圆零角零分整

90000009->玖仟万零玖圆整

90000000->玖仟万

90000009->玖仟万零玖

900000000->玖亿圆零角零分整

900000009->玖亿零玖圆整

900000000->玖亿

900000009->玖亿零玖

9000000000->玖拾亿圆零角零分整

9000000009->玖拾亿零玖圆整

9000000000->玖拾亿

9000000009->玖拾亿零玖

90000000000->玖佰亿圆零角零分整

90000000009->玖佰亿零玖圆整

90000000000->玖佰亿

90000000009->玖佰亿零玖

566949.58648 --> 伍拾陆万陆仟玖佰肆拾玖圆伍角玖分整

566949.58648 --> 伍拾陆万陆仟玖佰肆拾玖点伍玖

-------------结束----------------

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值