# -*- encoding:utf-8 -*-
'''
01 re模块方法中的re.search()和re.findall的区别:
(1)re.search():逐个寻找,寻找后就返回。
(2)re.findall():全部找到后一起返回。
02 ret和res的区别
(1)ret默认是return的缩写。
(2)res默认是result的缩写。
'''
import re
def cal_min_exp(min_exp):
'''
01 计算最小表达式中的乘除法
:param min_exp:
:return:
'''
if "*" in min_exp:
v1, v2 = min_exp.split("*") # 将min_exp按照乘法进行分割,因为min_exp是字符串“2*5”,所以需要分割。
return str(float(v1) * float(v2)) # 分割后强制转换为浮点型进行计算,最后要返回字符型,因为需要以字符型进行替换。
elif '/' in min_exp:
v1, v2 = min_exp.split("/")
return str(float(v1) / float(v2))
def dealwith(son_exp):
'''
整理加加减减去重
:param son_exp:
:return:
'''
son_exp = son_exp.replace('__', '+')
son_exp = son_exp.replace('+_', '-')
son_exp = son_exp.replace('++', '+')
son_exp = son_exp.replace('_+', '_')
return son_exp
def calculate(son_exp):
'''
01 计算没有括号的表达式
02 计算原则:先计算乘除,在计算加减
:param son_exp:
:return:
'''
son_exp = son_exp.strip("()")
while 1: # 用于完成表达式中的乘除法计算。
'''
匹配规则:\d+\.?\d*[*/]-?\d+\.?\d*
'''
ret = re.search("\d+\.?\d*[*/]-?\d+\.?\d*", son_exp)
if ret:
min_exp = ret.group()
res = cal_min_exp(min_exp) # 计算乘除法,并且将结果返回。
son_exp = son_exp.replace(min_exp, res, 1)
else:
break
son_exp = dealwith(son_exp) # 整理加加减减去重,例如 3-+1--2之类。
res = re.findall('[+-]?\d+\.?\d*', son_exp)
sum = 0
for i in res:
sum = sum + float(i)
return str(sum)
def remove_bracket(express):
'''
01 函数作用:把内部不再有小括号的表达式匹配出来,
02 正则表达式:\([^()]+\)
03 该处匹配的方法建议使用re.search,通过该方法进行一个个匹配,匹配后即返回,可以如果用re.findall全部取出会有一些不可预估
的问题出现。
'''
while 1:
ret = re.search('\([^()]+\)', express) # 根据正则逐个匹配出满足内部不再有小括号的表达式出来。
if ret: # 判断返回的表达式是否为真。
son_exp = ret.group() # 将子表达式表示出来,ret是个对象,通过调用函数group即可将表达式表示出来。
'''
01 取值后进行计算。
'''
ret = calculate(son_exp)
express = express.replace(son_exp, ret, 1) # 需要指定替换次数,否则全部替换的话,会将2*5000中前面的2*5也直接替换为计算后的值
else:
break
return express
def main(express):
express = express.replace(' ', '') # 首先去除表达式的空格。
express = remove_bracket(express) # 调用函数,去括号,把内部不再有小括号的表达式匹配出来。
ret = calculate(express)
print("计算结果:", ret)
if __name__ == '__main__': # 用于调试,如果未被调用时__name__等于__main__可以执行,如果被调用,则__name__等于模块名,不能执行当前文件。
print('输入计算的内容或输入Q退出'.center(30, '*')) #
while 1:
# express = '-1 + 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
express = input('please enter: ')
if express == 'Q' or express == 'q':
break
elif '/0' in express:
print('0不能为被除数')
elif express.count('(') != express.count(')') or '=' in express: # 统计()的是否是成对出现,并且算式中是否出现"="
print('表达式错误,请重新输入')
else:
main(express)