正则表达式实现计算器
计算器:实现带括号的+ - * /运算
需求分析:
8*5-2+(10-(8*5+6)/10+5)*(3-2)+8*(9-4)
1、从前到后找,找到第一个以(开始)结尾,中间不含有括号的表达式
2、正则表达式:\(^()\)
定义两个函数:
1、def 处理加减乘除(表达式):
return 结果
2、def 处理括号(表达式):
while True:
#先找到第一个,分割成三部分,得到括号内的表达式,不要括号
re.split('\( [^()] \)',表达式,1)
#8*5-2+(10- 8*5+6 /10+5)*(3-2)+8*(9-4)
ret = 加减乘除(8*5+6)
#再把表达式连起来
8*5-2+(10- ret /10+5)*(3-2)+8*(9-4)
import re import sys def no_bracket_rules(expression): '''计算没有括号的乘除运算''' md_check = re.search(r'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',expression) if md_check:#乘除存在 #得到第一个*或/运算表达式 data = md_check.group() if len(data.split("*")) > 1:# 当可以用乘号分割,证明有乘法运算 part1, part2 = data.split("*") # 用乘号分割 result = float(part1)*float(part2) else: part1, part2 = data.split("/")# 用除号分割 if part2 == 0: sys.exit("计算过程中有被除数为0的存在,计算表达式失败!") else: result = float(part1) / float(part2) # 获取第一个匹配到的乘除计算结果value,将value放回原表达式 # 以第一个*或/分割表达式 s1, s2 = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', expression, 1) # 将计算结果和剩下的表达式组合成新的字符串 new_exp = "%s%s%s" % (s1, result, s2) return no_bracket_rules(new_exp)#递归表达式 else:#乘除不存在,在判断加减是否存在 expression = expression.replace('+-', '-') # 替换表达式里的所有'+-' expression = expression.replace('--', '+') # 替换表达式里的所有'--' expression = expression.replace('-+', '-') # 替换表达式里的所有'-+' expression = expression.replace('++', '+') # 替换表达式里的所有'++' as_check = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression)#匹配加减号 if not as_check: # 如果不存在加减号,则证明表达式已计算完成,返回最终结果 return expression else: #得到第一个+或-运算表达式 data = re.search('[\-]?\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression).group() if len(data.split("+")) > 1: #以加号分割成功,有加法计算 part1, part2 = data.split('+') value = float(part1) + float(part2) # 计算加法 elif data.startswith('-'): # 如果是以'-'开头则需要单独计算,因为是负数 #分割为三部分,分别为'',正数,正数 part1, part2, part3 = data.split('-') value = -float(part2) - float(part3) # 计算以负数开头的减法 else: #正数的减法运算 part1, part2 = data.split('-') value = float(part1) - float(part2) # 计算减法 # 以第一个+或-分割表达式 s1, s2 = re.split('[\-]?\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression, 1) # 将计算后的结果替换回表达式,生成下一个表达式 new_exp = "%s%s%s" % (s1, value, s2) return no_bracket_rules(new_exp) # 递归运算表达式 # s = "8*5-2+10.4+6*1+8*9-4" # ret = no_bracket_rules(s) # print(ret,type(ret))#122.4 <class 'str'> def bracket_rules(expression): '''计算括号内的表达式''' while True: #验证表达式内是否含有以括号开始和结尾,且中间不含括号的 if re.findall(r"\(([^()]+)\)",expression): # 找到第一个以(开始,以)结尾,且中间不含()的表达式 s_split = re.split(r"\(([^()]+)\)",expression,1) ret = no_bracket_rules(s_split[1])#分割为三部分,中间为得到的表达式 # 将先前得到的表达式的计算结果和剩下的表达式组合成新的字符串 new_exp = "%s%s%s" % (s_split[0], ret, s_split[2]) return bracket_rules(new_exp)#返回函数,继续查找表达式 else: #如果表达式内没有括号,就直接调用加减乘除函数进行计算 result = no_bracket_rules(expression) return result s = "8*5-2+(10-(8*5+6)/10+5)+6*(3-2)+8*9-4" ret = bracket_rules(s) print(ret)#122.4