使用正则写一个计算器
eval 不能直接计算数字表达式
去掉s中的所有空格
写正则表达式 把内部不再有括号的表达式提取出来
写正则表达式 把a*b或者a/b这样的表达式从左到右依次匹配出来
写正则表达式 把加减法匹配出来
能够级匹配整数表达式 也匹配小数表达式
如果 你已经拿到一个 a+b 或者 a*b
写一个函数,计算这样表达式的结果
'1+5'
'1.345+2.567'
s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
import re s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )' s = s.replace(' ','') def mul_di(num): if '/' in num: a,b = num.split('/') return str(float(a)/float(b)) elif '*' in num: a,b = num.split('*') return str(float(a)*float(b)) def mul_div(num): while True: mu = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?',num) if mu: mul = mu.group() mun = mul_di(mul) num = num.replace(mul,mun) else:break return num def cha_sym(num): num = num.replace('++','+') num = num.replace('+-','-') num = num.replace('-+','-') num = num.replace('--','+') return num def add_sub(num): nu = re.findall('[+-]?\d+(?:\.\d+)?', num) count = 0 for i in nu: count += float(i) return str(count) def no_sp(num): while True: nu = re.search('\([^()]+\)',num) if nu: ret = nu.group() Value = mul_div(ret) Value = cha_sym(Value) new_Value = add_sub(Value) num = num.replace(ret,new_Value) else:break ret = mul_div(num) Value = cha_sym(ret) return add_sub(Value) print(no_sp(s))
递归做法
import re def calculator(e,n=0,round_num=5): if ' ' in e:e = e.replace(' ','') regex_lst = ['\(([\d\-\+\.\*\/])+\)', '(\d+\.\d+|\d+)(\*|\/)(\-?\d+\.\d+|\d+)', '(\+|\-){2,}','(\-|\+)?((\d+\.\d+)|\d+)'] for step in range(n,len(regex_lst)): regex = re.compile(regex_lst[step]) while 1: tmp = regex.finditer(e) if step==3 else regex.search(e) if not tmp: if step==0:return None if ('(' in e or ')' in e) else round(calculator(e,1),round_num) break if step == 3: return sum([float(i.group()) for i in tmp]) dic = {0:lambda:calculator(tmp.group()[1:-1],1), 1:lambda:float(tmp.group(1))*float(tmp.group(3)) if '*' in tmp.group(2) else float(tmp.group(1))/float(tmp.group(3)), 2:lambda:'+' if tmp.group().count('-')%2==0 else '-'} e = e.replace(tmp.group(), str(dic[step]())) s1 = '1+(2-3-4*5/ (-4 - 2)+ 4 5 )-494+5+54+45*452-45245/4524*525-452-(56+45)' print(calculator(s1))