利用pyhton中re模块与正则表达式进行长运算式(1 -2 *((60-30+(-40/5) * (9-2*5/3 + 7/3*99/4*2998+10 * 568/14)) -(-4*3)/)计算


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))

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值