利用正则写了一个简单的计算器,可以使用括号,加减乘除的运算。
计算方法:先去括号,括号中计算的结果替换括号中的内容,在做一般运算。
出现的问题:
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))