刚学完正则,利用正则写了一个简单的计算器,可以使用括号,加减乘除的运算。
计算方法:先去括号,括号中计算的结果替换括号中的内容,在做一般运算。
出现的问题:
1.要判断浮点型的数据,如123.456和123 即 \d+[.]?\d*
2.要判断两个数加减运算时,第一个数是负数,不能用计算乘除时的判断方法(用re.search找关键字)。如-100.11-20.1和-100.11+20.1 可以使用re.findall找出两个值直接相加。
x, y = re.findall('[+-]?\d+[.]?\d*', ret1) # ['-100.11','-20.1']
jj_res = str(float(x) + float(y)) # -120.21
3.去括号时,可以使用递归方法,直到判断出没有括号。
1 #calc by slitobo 20180614 2 import re 3 #检查字符串合规 4 def check_str(s): 5 flag=True 6 if re.findall('[a-zA-Z]',s): 7 print('Invalid args. pls check input') 8 flag=False 9 return flag 10 #格式化字符串 11 def format_str(s): 12 s=s.replace(' ','') 13 # s=re.sub('\+-|-\+','-',s) 14 return s 15 #去括号 16 def qukuohao(s): 17 #判断有括号执行 18 if re.findall('[()]',s): 19 # retold保持括号中的值,括号计算的结果ret替换retold,如retold=(1+2+3) ret=6 20 retold = re.search('\([^()]+\)', s).group() 21 # 获取最里面括号的内容,ret最后的值不带括号 22 ret = re.search('\([^()]+\)', s).group() 23 # 计算前去掉括号 24 ret = ret[1:-1] 25 #一般运算 26 ret=ncalc(ret) 27 s = s.replace(retold, ret) 28 return qukuohao(s) 29 return s 30 #一般运算 31 def ncalc(ret): 32 #先算乘除 33 while re.findall('[*/]', ret): 34 # ret1为括号中待计算的乘除内容 35 ret1 = re.search('\d+[.]?\d*[*/]\d+[.]?\d*', ret).group() #print(ret1, type(ret1)) # 5*3 <class 'str'> 36 if re.search('[*/]', ret1).group() == '/': 37 x, y = re.split('\/', ret1) 38 div_res = str(float(x) / float(y)) 39 ret = ret.replace(ret1, div_res) 40 elif re.search('[*/]', ret1).group() == '*': 41 a, b = re.split('\*', ret1) 42 chen_res = str(float(a) * float(b)) 43 ret = ret.replace(ret1, chen_res) 44 # 再算加减 45 while re.findall('\d+[.]?\d*[+-]', ret): 46 # ret1为括号中待计算的加减内容 # 5*3 <class 'str'> 47 ret1 = re.search('[-]?\d+[.]?\d*[+-]\d+[.]?\d*', ret).group() 48 x, y = re.findall('[+-]?\d+[.]?\d*', ret1) 49 jj_res = str(float(x) + float(y)) 50 ret = ret.replace(ret1, jj_res) 51 return ret 52 53 # ss='1 - 2 * (60-3*6+(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 ))-((0.1+3.0/5+6*4+10) + (1+3*4)) * 7' 54 ss='-1.2-3.2+3*4/a' 55 56 if check_str(ss): 57 ss=format_str(ss) 58 result=ncalc(qukuohao(ss)) 59 print('%s 计算结果是:%s' %(ss,result))