环境:
- python 3*
- pycharm
用户需求 :
- 实现加减乘除及拓号优先级解析:
- 用户输入 >>>
1 - 2 * ( (60-30 +(-40/5) * (9-25/3 + 7 /399/42998 +10 * 568/14 )) - (-43)/ (16-3*2) )
等类似公式后,计算结果
- 分析:
解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器>所得出的结果一致
思路:
1、匹配最里层括号中的内容
2、逐步计算细节:
1、多余空格处理
2、算数表达式的合法性
3、处理 ‘++’、 ‘–’、 ‘±’、 ‘-+’、 ‘+’、 ‘+’ …
re 模块学习笔记
程序
# Author: Langkye
# Data: 2019/9/24
import re
# 检查表达式的合法性
def check_expression(s):
check_result = True
if not s.count('(') == s.count(')'): # 左括号和右括号是否一致
print('Expression error . Missing ")" of "("') # 缺失 左括号 或者 右括号
check_result = False
if re.findall(r'[^0-9+\-\*/()\s]+',s.lower()): # 判断表达式是否含有 一个或多个 字母、特殊字符 r'[^0-9+\-\*/()\s]+' #|# 一个或多个字母集[a-zA-Z]+
print('Expression Error . Exist other character') # 表达式包含其它字符
check_result = False
return check_result
# 规范化表达式
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('/+','/')
s = s.replace('+/','/')
s = s.replace(' ','')
return s
# 乘除法
def calc_mul_div(s):
# re 规则
regular = '\d+\.?\d*([*/]|[\*\*])[\-]?\d+\.?\d*'
while re.findall(regular,s):
expression = re.search(regular,s).group() # 找出满足 乘、除 法规则的第一个结果
if expression.count('*') == 1: # 计算乘法
x, y = expression.split('*')
mul_result = str(float(x) * float(y))
s = s.replace(expression,mul_result) # 将计算结果 ,替换原先的表达式
s = format_string(s) # 规范化 ‘++’
if expression.count('/'): # 计算除法
x, y = expression.split('/')
div_result = str(float(x) / float(y))
s = s.replace(expression,div_result)
s = format_string(s)
if expression.count('**'): # 计算幂
x, y = expression.split()
pow_result = 1
for i in range(int(y)):
pow_result *= int(x)
s = s.replace(expression,str(pow_result))
s = format_string(s)
return s
# 加减法
def calc_add_sub(s):
# 加法正则 # 匹配 x + y :x、y可为任意有理数 # [\-]? :0或1个“-” ;\d+ :1或多个数字;\.? :0或1个小数点 ; \d* :0或多个数字 ; \d+ :1或多个数字 ; \.? 0或1个小数点 ; \d* :0或多个数字
add_regular = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'
# 减法正则 # 同理 匹配 x - y
sub_regular = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'
while re.findall(add_regular,s): # 计算加法
add_list = re.findall(add_regular,s)
for add_str in add_list:
x, y = add_str.split('+')
add_result = '+' + str(float(x) + float(y))
s = s.replace(add_str,add_result)
s = format_string(s)
while re.findall(sub_regular,s): # 计算减法
sub_list = re.findall(sub_regular,s)
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)
s = s.replace(sub_str,'+'+str(result))
s = format_string(s)
return s
# 主函数
def main(expression = ''):
if check_expression(expression):
print('source:\t',expression)
print('最终结果:',eval(expression))
source = format_string(expression)
print('格式化:\t',source)
num = 1
while source.count('(') > 0:
# 取出里层括号内的表达式
strs = re.search('\([^()]*\)',source).group() # --------------------------
replace_str = calc_mul_div(strs) # -----------------------------------
replace_str = calc_add_sub(replace_str) # ----------------------------
replace_str=format_string(replace_str)
source = format_string(source.replace(strs,replace_str[1:-1])) # ----------------
else:
replace_str = calc_mul_div(source)
replace_str = calc_add_sub(replace_str)
source = source.replace(source,replace_str)
print('计算结果:',source.replace('+',''))
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+1'
while True:
source = input('\n%sEnter an expression%s\nEnter [Q] to Exit\n>>>'%('-'*20, '-'*20))
if source == 'q' or source == 'Q':
break
else:
main(source)
?