python 利用正则构建一个计算器

该计算器主要分为四个模块:

weclome_func函数用来进入界面获取表达式,并判断表达式是否正确,然后返回表达式;

add_sub函数用来进行加减运算,如果有多个加减运算,会递归,最后返回对应的值

multi_divide函数用来进行乘除运算,如果有多个乘除运算,会递归,最后返回对应的值

del_bracket函数用来去除小括号及调用multi_divide和add_sub函数,如果存在多个括号,也会实现递归。

代码如下:

#! /usr/bin/env python3

import sys
import re

def welcome_func():
    flag_exit = True
    welcome_str = "超级计算器"
    print(welcome_str.center(50, "*"), '
')
    while flag_exit:
        exp = input("请输入要计算的表达式[q:退出]: ").strip()
        if exp == "q":
            flag_exit = False
        elif len(exp) == 0:
            continue
        else:
            exp = re.sub("s*", '', exp)     ## 取出空格
            return exp

def multi_divide(expression):
    val = re.search("d+.?d*[*/][+-]?d+.?d*", expression)    ##匹配乘除号,如192.168*-1.99
    if not val:    # 乘除号不存在,返回输入的表达式
        return expression
    data = re.search("d+.?d*[*/][+-]?d+.?d*", expression).group()
    if len(data.split('*')) > 1:           # 当可以用乘号分割,证明有乘法运算
        part1, part2 = data.split('*')     # 用除号分割
        value = float(part1) * float(part2)
    else:
        part1, part2 = data.split('/')
        if float(part2) == 0:            # 如果分母为0,则退出计算
            sys.exit("计算过程中有被除数为0的存在,计算表达式失败!")
        value = float(part1) / float(part2)

    s1, s2 = re.split("d+.?d*[*/][+-]?d+.?d*", expression, 1)  # 分割表达式
    next_expression = "%s%s%s" % (s1, value, s2)
    return multi_divide(next_expression)      # 递归表达式

def add_sub(expression):
    expression = expression.replace('+-', '-')      # 替换表达式里的所有‘+-‘
    expression = expression.replace('--', '+')      # 替换表达式里的所有‘--‘
    expression = expression.replace('-+', '-')      # 替换表达式里的所有‘-+‘
    expression = expression.replace('++', '+')      # 替换表达式里的所有‘++‘

    data = re.search('d+.?d*[+-]d+.?d*', expression)    # 匹配加减号
    if not data:                    # 如果不存在加减号,则证明表达式已计算完成,返回最终结果
        return expression
    val = re.search('[+-]?d+.?d*[+-]d+.?d*', expression).group()
    if len(val.split('+')) > 1:                   # 以加号分割成功,有加法计算
        part1, part2 = val.split('+')
        value = float(part1) + float(part2)
    elif val.startswith('-'):                     # 如果是已‘-‘开头则需要单独计算
        part1, part2, part3 = val.split('-')
        value = -float(part2) - float(part3)      # 计算以负数开头的减法
    else:
        part1, part2 = val.split('-')
        value = float(part1) - float(part2)

    s1, s2 = re.split('[+-]?d+.?d*[+-]d+.?d*', expression, 1)    # 分割表达式
    next_expression = "%s%s%s" % (s1, value, s2)
    return add_sub(next_expression)              # 递归运算表达式

def del_bracket(expression):

    ## [^()]+  匹配除了括号以外的任意字符

    if not re.search(r"([^()]+)", expression):   # 判断小括号,如果不存在小括号,直接调用乘除,加减计算
        ret1 = multi_divide(expression)
        ret2 = add_sub(ret1)
        return ret2                      # 返回最终计算结果
    data = re.search(r"([^()]+)", expression).group()    # 如果有小括号,匹配出优先级最高的小括号
    print("获取表达式", data)
    data = data.strip('[()]')           # 剔除小括号
    ret1 = multi_divide(data)
    # print("全部乘除计算完后的表达式:", ret1)
    ret2 = add_sub(ret1)
    # print("全部加减计算结果:", ret2)
    part1, part2 = re.split(r"([^()]+)", expression, 1)         # 分割表达式
    expression = "%s%s%s" % (part1, ret2, part2)
    return del_bracket(expression)                         # 递归去小括号

if __name__ == "__main__":
    try:
        expression = welcome_func()     ## 获取表达式
        print(expression)
        result = eval(expression)       ## 用eval来验证
        print(result)
        ret = del_bracket(expression)   ## 用函数计算得出结果
        result = float(result)
        ret = float(ret)
        print("eval计算结果: ", result)
        print("表达式计算结果: ", ret)
    except (SyntaxError, ValueError, TypeError):
        print("输入表达式不合法,请检查!")
原文地址:https://www.cnblogs.com/654wangzai321/p/8166355.html