1、实现加减乘除及拓号优先级解析
2、用户输入带有加减乘除小括号的复杂运算公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致
# -*- coding:utf-8 -*-
import re
def check(string): #检查是否有其他特殊字符字母,检查表达式合法性
flag=True
if re.findall('[a-z]',string.lower()):
print('表达式错误,包含非法字符')
flag=False
if not string.count("(") == string.count(")"):
print("表达式错误,括号未闭合")
flag=False
return flag
def format_string(s): #格式化字符串 :去掉空格
s=s.replace(' ','')
s=s.replace('--','+')
s=s.replace('++','+')
s=s.replace('+-','-')
s=s.replace('-+','-')
s=s.replace('*+','*')
s=s.replace('/+','/')
return s
def cal_mul_div(string): #计算乘除,如(30+6*2+9/3)
# ret1=re.search('\d+\.?\d*[*/]\d+\.?\d*',s) #匹配小数\d+\.?\d*,匹配乘或除[*/]
regular='\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
while re.search(regular,string):
expression = re.search(regular,string).group() #获取表达式6*2
if expression.count("*")==1: #如果是乘法
x,y = expression.split("*") #获取要计算的2个数
mul_result = str(float(x) * float(y))
string = string.replace(expression,mul_result) #将计算的表达式替换为计算结果值
string = format_string(string) #格式化
if expression.count("/"): #如果是除法
x,y = expression.split("/")
div_result = str(float(x) / float(y))
string = string.replace(expression,div_result)
string = format_string(string)
if expression.count("*")==2: #如果是乘方
x,y=expression.split('**')
pow_result=1
for i in range(int(y)):
pow_result*=int(x)
string=string.replace(expression,str(pow_result))
string=format_string(string)
return string
def cal_add_sub(string): #计算加减
# ret1 = re.search('\d+\.?\d*[+-]\d+\.?\d*', s) # 匹配小数\d+\.?\d*,匹配加或减[+-]
add_regular='[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'
sub_regular='[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'
while re.findall(add_regular,string): #加法
add_list = re.findall(add_regular,string)
for add_str in add_list:
x,y = add_str.split("+")
add_result = "+" + str(float(x) + float(y))
string = string.replace(add_str, add_result)
string = format_string(string)
while re.findall(sub_regular,string): #减法
sub_list = re.findall(sub_regular,string)
for sub_str in sub_list:
numbers = sub_str.split("-")
if len(numbers) == 3:
result = 0
for v in numbers:
if v:
result -= float(v)
else:
x,y = numbers
result = float(x) - float(y)
return string
if __name__ == "__main__":
# source = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
source = '1-2*3+9/3-(1+1+(2-1)*1)'
if check(source):
print("source:",source)
print("eval result:",eval(source))
source=format_string(source)
print(source)
# while re.search('\('):
while source.count('(') > 0:
strs=re.search('\([^()]+\)',source).group() #找到最里面的()
repalce_str=cal_mul_div(strs) #将括号里面的表达式进行乘除运算(2+15)
replace_str=cal_add_sub(repalce_str) #将括号里面的表达式进行加减运算 '(17)'
source=format_string(source.replace(strs,repalce_str[1:-1])) #将括号的字符串替换为计算结果,结果包含(),替换时去掉():[1:-1]
else: #没有括号就到最后单一表达式了
strs = cal_mul_div(strs) # 算乘除
strs = cal_add_sub(strs) # 算加减
source = source.replace(source,replace_str)
print("my result:",source.replace("+",""))