展开全部
# -*- coding:utf-8 -*-
binaryDic={'+':float.__add__,
'-':float.__sub__,
'*':float.__mul__,
'/':float.__truediv__,
'%':float.__mod__,
'**':float.__pow__,}
unaryDic={'-':float.__neg__,
'+':float.__pos__,}
priorDic=dict((('**',3),('*',2),('/',2),('%',2),('+',1),('-',1)))
def is_float(s):
'判断是否浮点数字符'
return s.isdigit() or s=='.'
def is_prior(firOpf,secOpf):
'判断运2113算符的优5261先级'
if secOpf=='**':
return False
return priorDic[firOpf]>=priorDic[secOpf]
def wipe_brace(s,start=0):
's是以左括号开头的字符串4102'
'此函数将消去括号,求出括1653号内的值,并返回剩余字符'
pos=s.find(')',start)
if s[1:pos].count('(')==s[1:pos].count(')'):
return s[pos+1:] ,ieval(s[1:pos])
return wipe_brace(s,pos+1)
def get_Longest_number(s,num=''):
's是以左括号或数字开头的字符串'
'返回s首位开始的最长连续数字串和剩余字符串'
if not s :
return s,num
if s[0]=='(':
return wipe_brace(s)
if is_float(s[0]):
return get_Longest_number(s[1:],num+s[0])
return s,num
def get_val(fir='',opf='',sec=''):
'智能求值函数.能进行一元,二元或纯值运算'
if opf:
if sec:
return str(binaryDic[opf](float(fir),float(sec)))
return str(unaryDic[opf](float(fir)))
return fir
def get_safeSec(s,cmpOpf='**',neg='',safeSec='',):
'比较s的第一个二元运算符和cmpOpf的优先级'
'以便获得安全的第二个值'
if not s:
return s,get_val(safeSec,neg)
if not safeSec:
if s[0]=='+':
return get_safeSec(s[1:],cmpOpf,neg)
if s[0]=='-':
return get_safeSec(s[1:],cmpOpf,'' if neg=='-' else '-')
if is_float(s[0]) or s[0]=='(':
rest,safeSec=get_Longest_number(s)
return get_safeSec(rest,cmpOpf,neg,safeSec)
opfNum= 2 if s[:2]=='**' else 1
if is_prior(cmpOpf,s[:opfNum]):
return s,get_val(safeSec,neg)
rest,safeNum=get_safeSec(s[opfNum:],s[:opfNum])
return get_safeSec(rest,cmpOpf,neg,get_val(safeSec,s[:opfNum],safeNum))
def ieval(s='',fir='',opf='',sec=''):
'控制整个解析流程'
if not s:
return get_val(fir,opf,sec)
if not fir:
if s[0]=='-':
return ieval(s[1:],fir,'' if opf=='-' else '-')
if s[0]=='+':
return ieval(s[1:],fir,opf)
if is_float(s[0]) or s[0]=='(':
return ieval(*get_Longest_number(s),opf=opf)
if not sec:
if not opf:
opfNum= 2 if s[:2]=='**' else 1
rest,sec=get_safeSec(s[opfNum:],s[:opfNum])
return ieval(rest,fir,s[:opfNum],sec)
if s[:2]!='**':
return ieval(s,get_val(fir,opf))
rest,sec=get_safeSec(s[2:])
return ieval(rest,get_val(fir,'**',sec),opf)
return ieval(s,get_val(fir,opf,sec))
if __name__=='__main__':
test=['1+2*3*4*5+20',
'1+2*3',
'1.1+20.02+300.003',
'-2**2',
'(-2)**2',
'1+2*3**-2**(2-3)*2',
'-2**-2**-2**-2',
'(1+2)*(2+3)/(1-3)',
'((9+3)/2)',
'((1234)-1)',
'1-3*--+++-2**--+++((-2))**--+++-(1-2)**--+++-2*2+1*2**6%9',
'((1+3*(-2)**2)*((2%3+((3+3)*2**3+1))*(1-3)*(1+2)+5*6)*4)']
for x in test:
print(ieval(x),'___',eval(x))
结果:>>>
141.0 ___ 141
7.0 ___ 7
321.123 ___ 321.123
-4.0 ___ -4
4.0 ___ 4
3.309401076758503 ___ 3.309401076758503
-0.5582965649524321 ___ -0.5582965649524321
-7.5 ___ -7.5
6.0 ___ 6.0
1233.0 ___ 1233
6.242640687119286 ___ 6.242640687119286
-14352.0 ___ -14352