# 开发一个简单的python计算器
# 实现加减乘除及括号优先级解析
# 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
# 等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致
一.对公式进行简单处理(去掉空格及公式化简)
import re def format_string(string): string = string.replace(' ','') string = string.replace('++','+') string = string.replace('+-','-') string = string.replace('-+','-') string = string.replace('--','+') string = string.replace('*+','*') string = string.replace('/+','/') return string
二.对于不符合要求的公式进行异常处理,给出错误提示信息
def check_expression(string): check_result = True if not string.count("(") == string.count(")"): print('括号不对称') check_result = False if re.findall('[a-z]',string.lower()): print('表达式有错,包含非法字符') check_result = False return check_result
三.进行乘除运算,并将计算的结果替换掉原公式中的乘除法运算
def mul_div(string):
#正则表达式匹配(x乘以y或x除以y) regular = '\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
#一直到公式中没有除法或乘法运算时,退出循环 while re.findall(regular,string): expression = re.search(regular,string).group()
#计算乘法,并将计算的结果替换原来的式子 if expression.count("*") == 1: x,y = expression.split('*') 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) return string
四.进行加减法运算
def add_sub(string): sub_regu = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*' add_regu = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*' #计算加法 while re.findall(add_regu,string): add_list = re.findall(add_regu,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) #计算减法 while re.findall(sub_regu,string): sub_list = re.findall(sub_regu,string) for sub_str in sub_list: numbers = sub_str.split('-') if len(numbers) == 3: result = 0 #计算-1-2这种情况 for v in numbers: if v: result -= float(v) else: x,y = numbers result = float(x)-float(y) string = string.replace(sub_str,"+" + str(result)) string = format_string(string) return string
五.轮子造好了,主逻辑程序
if __name__ =="__main__":
if check_expression(source): strs = format_string(source) while source.count('(') > 0:
#匹配最里层括号的内容 strs = re.search('\([^()]*\)',source).group() replace_str = mul_div(strs) replace_str = add_sub(replace_str)
#每次计算的结果去掉括号 source = format_string(source.replace(strs,replace_str[1:-1])) # print(source)
#else下边的逻辑是计算不带括号的式子 else: replace_str = mul_div(source) replace_str = add_sub(replace_str) source = source.replace(source,replace_str) print(source)
六.总结-难点
1.匹配最里层的式子:'\([^()]*\)'
2.匹配乘除法及加减法的正则表达式
3.主逻辑的设计
七.总程序
import re def format_string(string): string = string.replace(' ','') string = string.replace('++','+') string = string.replace('+-','-') string = string.replace('-+','-') string = string.replace('--','+') string = string.replace('*+','*') string = string.replace('/+','/') return string def mul_div(string): "计算乘除运算,所得的结果替换原先的表达式返回" regular = '\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*' while re.findall(regular,string): expression = re.search(regular,string).group() if expression.count("*") == 1: x,y = expression.split('*') 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) return string def add_sub(string): sub_regu = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*' add_regu = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*' #计算加法 while re.findall(add_regu,string): add_list = re.findall(add_regu,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) #计算减法 while re.findall(sub_regu,string): sub_list = re.findall(sub_regu,string) for sub_str in sub_list: numbers = sub_str.split('-') if len(numbers) == 3: result = 0 #计算-1-2这种情况 for v in numbers: if v: result -= float(v) else: x,y = numbers result = float(x)-float(y) string = string.replace(sub_str,"+" + str(result)) string = format_string(string) return string def check_expression(string): check_result = True if not string.count("(") == string.count(")"): print('表达式有错,括号不对') check_result = False if re.findall('[a-z]',string.lower()): print('表达式有错,包含非法字符') check_result = False return check_result 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) )' if check_expression(source): strs = format_string(source) while source.count('(') > 0: strs = re.search('\([^()]*\)',source).group() replace_str = mul_div(strs) replace_str = add_sub(replace_str) source = format_string(source.replace(strs,replace_str[1:-1])) else: replace_str = mul_div(source) replace_str = add_sub(replace_str) source = source.replace(source,replace_str) print(source)
浙公网安备 33010602011771号