import re
'''
计算结果
1.先去空格
2.去除()内只有float型数据的()只去除一层
3.去除-+/+-/--/++的情况
4.计算括号内的值先乘除,再加减
5.确保每次的最内层括号乘除与加减需要算完,确保函数返回值不带*/与+-
6.最终判断计算结果是否是一个数字,如果是结束,如果不是继续上面的步骤
'''
string = '1 -2 *((60-30+(-40/5) * (9-2*5/3 + 7/3*99/4*2998+10 * 568/14)) -(-4*3)/(16-3*2))'
# ret = re.compile("[^()]+(?=[)])")#表达式不完全
# ret_in_pracket = re.compile(r"([^()]+[*/]+\d+)(?=[)])") # 匹配内层括号的算式
ret_mul_div = re.compile(r"(\d+(?:\.\d+)?)([*/])([-]?\d+(\.\d+)?)")
# 匹配乘除法,处理括号内的长算式,以分组将算式进行最小分割,只包括最小的乘除计算,
# 循环匹配时注意可能出现小数,正则式需要考虑
ret_add_sub = re.compile(r"([-]?\d+\.?\d*)([+-])(\d+(\.?\d*))(?!\*)")
# 加法正则匹配,该正则式不严谨,会匹配"3."类型
ret_in_float_pracket = re.compile(r"(\()([-]?\d+(?:\.\d+)?)(\))")
# 匹配()内的正负数,仅为数字不包括运算符号
ret_replace_add_sub = re.compile(r"[+-]{2}") # 匹配重复加减号
result = string.replace(' ', '') # 格式化字符串
def run_in_pracket(result):
'''
:param result: 带入有多层括号的算式,其中存在(正负小数)占有一个括号
去除该类型的内层括号
:return: 返回整体算式,带入算式符号处理的函数
'''
flag = ret_in_float_pracket.search(result)
if flag:
num = flag.group(2) # 正则式中的group(2)是计算符号
result = re.sub(ret_in_float_pracket, num, result, count=1)
return run_in_pracket(result)
else:
return result
def run_replace_add_sub(result):
'''
:param result: 为run_in_pracket函数处理过的整个算式
处理+-/-+/++/--的情况
:return: 返回一个能够匹配"ret_mul_div"或者"ret_add_sub"正则式的算式
'''
flag = ret_replace_add_sub.search(result)
if flag:
# new_flag = flag.group()
# if new_flag == '+-' or '-+':
# result = re.sub(ret_replace_add_sub, '-', result, count=1)
#
# return run_replace_add_sub(result)
# if new_flag == '--' or '++':#不进行条件判断,原因未知
# result = re.sub(ret_replace_add_sub, '+', result, count=1)
#
# return run_replace_add_sub(result)
result = re.sub(r'\-\+', '-', result, count=1)
result = re.sub(r'\+\-', '-', result, count=1)
result = re.sub(r'\-\-', '+', result, count=1)
result = re.sub(r'\+\+', '+', result, count=1)
return run_replace_add_sub(result)
else:
return result
def run_mul_div(result):
'''
:param result:带入处理过的整体算式
:return: 最内层无乘除法的整体算式
'''
flag = ret_mul_div.search(result)
if flag:
if flag.group(2) == '*':
result_num = float(flag.group(1)) * float(flag.group(3))
result = re.sub(ret_mul_div, str(result_num), result, count=1)
return run_mul_div(result)
elif flag.group(2) == '/':
result_num = float(flag.group(1)) / float(flag.group(3))
result = re.sub(ret_mul_div, str(result_num), result, count=1)
return run_mul_div(result)
else:
return result
def run_add_sub(result):
'''
:param result:内层无乘除法的算式
:return: 内层无加减法的算式
'''
flag = ret_add_sub.search(result)
if flag:
if flag.group(2) == '+':
result_num = float(flag.group(1)) + float(flag.group(3))
result = re.sub(ret_add_sub, str(result_num), result, count=1)
return run_add_sub(result)
elif flag.group(2) == '-':
result_num = float(flag.group(1)) - float(flag.group(3))
result = re.sub(ret_add_sub, str(result_num), result, count=1)
return run_add_sub(result)
else:
return result
def run_console(result):
'''
进行函数控制,每次在递归过程中所传递的值都是需要处理的整体算式
:param result:
:return:
'''
try:
result = float(result) # 令结果转化为一个数字,
return result # 能转为数字则结束递归返回计算结果
except ValueError: # 不能转化则处理ValueError错误,则继续进行处理
result = run_in_pracket(result)
print('1.', result)
result = run_replace_add_sub(result)
print('2.', result)
result = run_mul_div(result)
print('3.', result)
result = run_add_sub(result)
print('4.', result)
return run_console(result)
print(eval(result))
print(run_console(result))
利用pyhton中re模块与正则表达式进行长运算式(1 -2 *((60-30+(-40/5) * (9-2*5/3 + 7/3*99/4*2998+10 * 568/14)) -(-4*3)/)计算
最新推荐文章于 2021-11-22 10:48:24 发布