1.首先写运算式的正则表达式(加减,乘除,乘负数,除负数,匹配括号最里层)
l1_expression = re.compile(r'(-?d+)(.d+)?[-+](-?d+)(.d+)?') #匹配加减的正则表达式
l2_expression = re.compile(r'(-?d+)(.d+)?[/*](-?d+)(.d+)?') #匹配乘除的正则表达式
l3_expression = re.compile(r'(-?d+)(.d+)?*-(-?d+)(.d+)?') #匹配乘负数的正则表达式
l4_expression = re.compile(r'(-?d+)(.d+)?/-(-?d+)(.d+)?') #匹配除负数的正则表达式
l5_expression = re.compile(r'([^()]*)') #匹配包含括号的正则表达式
compile()编译正则表达式模式,返回一个对象的模式
根据表达式匹配数字的时候首先得判断匹配表达式的公式的时候第一个数字是什么数字(如:正负浮点数'0.1'or'-0.1',正负整型'1'or'-1',)
2.然后写计算公式的方法(Formula computing:公式计算,operator:操作符,multiple:多个,parentheses:小括号)
首先写一个匹配算式运算的符号,用来处理输入的表达式
def one_operator(string):
if string.count('+') == 1:
return str(float(string[:string.find('+')]) + float(string[string.find('+') + 1:])) #匹配加号前面和加号加字符串后面的算式
elif string[1:].count('-') == 1: #string[1:]是为了匹配开头是负数的字符串
return str(float(string[:string.find('-', 1)]) - float(string[string.find('-', 1) + 1:])) #从第一个元素开始找(防止从头开始匹配的直接就是负数)
elif string.count('*') == 1:
return str(float(string[:string.find('*')]) * float(string[string.find('*') + 1:])) #匹配乘法然后用字符串拼接起来
elif string.count('/') == 1:
return str(float(string[:string.find('/')]) / float(string[string.find('/') + 1:])) #匹配除法用字符串拼接起来
在定义一个匹配算式运算,不匹配括号,用来计算被处理过的算式运算.
def multiple_operator(string):
if string.count('+') + string.count('*') + string.count('/') == 0 and string[1:].find('-') < 0: #如果找到+/*等于0个元素和从第一个元素开始往后没有-号输出字符串
return string
elif string.count('+-') + string.count('--') + string.count('*-') + string.count('/-') != 0: #如果算是里面有运算负数的话执行以下步骤
string = string.replace("+-",'-') #以数学运算的方式转换运算符"+-"替换成'-'
string = string.replace("--",'+')
if string.count('*-') != 0: #处理乘负数
string = string.replace(l3_expression.search(string).group(),'-'+l3_expression.search(string).group().replace('*-','*')) #乘负先计算出结果然后转换为负数
if string.count('/-') != 0: #处理除负数
string = string.replace(l4_expression.search(string).group(),'-'+l4_expression.search(string).group().replace('/-','*'))
return multiple_operator(string) #最后用递归的方式把结果传给自己直到把所有的负数转换为可执行的运算式
elif string.count('*') + string.count('/') != 0: #处理乘除
ret = l2_expression.search(string).group() #调用re处理乘除的表达式,把结果赋值给一个新的变量
string = string.replace(ret, one_operator(ret)) #然后把结果和放到符号处理的函数里的结果(重新拼接算式)换一下
return multiple_operator(string) #用递归的方式直到把乘除表达式的结果完全运算出来
elif string.count('+') != 0 or string.count('-') != 0: #处理加减
ret = l1_expression.search(string).group() #调用re处理加减的表达式,把计算出的结果赋值给一个新的变量
string = string.replace(ret, one_operator(ret)) #然后把结果放入到符号处理的函数里的结果(重新皮杰算式)转换一下
return multiple_operator(string) #最后用递归的方式把所有的加减的结果完全计算出来
最后需要定义一个用来匹配括号的算式运算(先计算最里面括号的算式,逐层往外推,直到没有括号).
def parentheses(string):
if string.find('(') == -1: #如果表达式没有括号
return multiple_operator(string) #调用计算运算式的函数处理其结果
else:
ret = l5_expression.search(string).group() #处理括号里面的表达式(现在只是把最里层的括号拿出来了)赋值给一个新的变量
string = string.replace(ret,multiple_operator(ret[1:-1])) #然后把新的表达式和最新的表达式的运算结果转换一下(把最里层的括号的结果计算一下)
return parentheses(string) #最后继续匹配括号,知道取出所有括号并把结果取出来
3.等到功能完善之后调试调用函数以及计算公式的表达式
stat_print = print("计算器3.0版
输入'q'退出程序")
while True:
formula_computing = input("请输入计算公式:")
formula_computing = formula_computing.replace(" ","")
if formula_computing == "q":
print('谢谢使用~')
break
else:
print("计算结果:",parentheses(formula_computing))