正则表达式实现计算器

计算器:实现带括号的+ - * /运算
需求分析:
8*5-2+(10-(8*5+6)/10+5)*(3-2)+8*(9-4)
1、从前到后找,找到第一个以(开始)结尾,中间不含有括号的表达式
2、正则表达式:\(^()\)
定义两个函数:
1、def 处理加减乘除(表达式):
return 结果
2、def 处理括号(表达式):
while True:
#先找到第一个,分割成三部分,得到括号内的表达式,不要括号
re.split('\( [^()] \)',表达式,1)
#8*5-2+(10- 8*5+6 /10+5)*(3-2)+8*(9-4)
ret = 加减乘除(8*5+6)
#再把表达式连起来
8*5-2+(10- ret /10+5)*(3-2)+8*(9-4)
import re
import sys
def no_bracket_rules(expression):
    '''计算没有括号的乘除运算'''
    md_check = re.search(r'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',expression)
    if md_check:#乘除存在
        #得到第一个*或/运算表达式
        data = md_check.group()
        if len(data.split("*")) > 1:# 当可以用乘号分割,证明有乘法运算
            part1, part2 = data.split("*") # 用乘号分割
            result = float(part1)*float(part2)
        else:
            part1, part2 = data.split("/")# 用除号分割
            if part2 == 0:
                sys.exit("计算过程中有被除数为0的存在,计算表达式失败!")
            else:
                result = float(part1) / float(part2)
        # 获取第一个匹配到的乘除计算结果value,将value放回原表达式
        # 以第一个*或/分割表达式
        s1, s2 = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', expression, 1)
        # 将计算结果和剩下的表达式组合成新的字符串
        new_exp = "%s%s%s" % (s1, result, s2)
        return no_bracket_rules(new_exp)#递归表达式
    else:#乘除不存在,在判断加减是否存在
        expression = expression.replace('+-', '-')  # 替换表达式里的所有'+-'
        expression = expression.replace('--', '+')  # 替换表达式里的所有'--'
        expression = expression.replace('-+', '-')  # 替换表达式里的所有'-+'
        expression = expression.replace('++', '+')  # 替换表达式里的所有'++'
        as_check = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression)#匹配加减号
        if not as_check:   # 如果不存在加减号,则证明表达式已计算完成,返回最终结果
            return expression
        else:
            #得到第一个+或-运算表达式
            data = re.search('[\-]?\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression).group()
            if len(data.split("+")) > 1: #以加号分割成功,有加法计算
                part1, part2 = data.split('+')
                value = float(part1) + float(part2)  # 计算加法
            elif data.startswith('-'):  # 如果是以'-'开头则需要单独计算,因为是负数
                #分割为三部分,分别为'',正数,正数
                part1, part2, part3 = data.split('-')
                value = -float(part2) - float(part3)  # 计算以负数开头的减法
            else:  #正数的减法运算
                part1, part2 = data.split('-')
                value = float(part1) - float(part2)  # 计算减法
            # 以第一个+或-分割表达式
            s1, s2 = re.split('[\-]?\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression, 1)
            # 将计算后的结果替换回表达式,生成下一个表达式
            new_exp = "%s%s%s" % (s1, value, s2)
            return no_bracket_rules(new_exp)  # 递归运算表达式


# s = "8*5-2+10.4+6*1+8*9-4"
# ret = no_bracket_rules(s)
# print(ret,type(ret))#122.4 <class 'str'>

def bracket_rules(expression):
    '''计算括号内的表达式'''
    while True:
        #验证表达式内是否含有以括号开始和结尾,且中间不含括号的
        if re.findall(r"\(([^()]+)\)",expression):
            # 找到第一个以(开始,以)结尾,且中间不含()的表达式
            s_split = re.split(r"\(([^()]+)\)",expression,1)
            ret = no_bracket_rules(s_split[1])#分割为三部分,中间为得到的表达式
            # 将先前得到的表达式的计算结果和剩下的表达式组合成新的字符串
            new_exp = "%s%s%s" % (s_split[0], ret, s_split[2])
            return bracket_rules(new_exp)#返回函数,继续查找表达式
        else:
            #如果表达式内没有括号,就直接调用加减乘除函数进行计算
            result = no_bracket_rules(expression)
            return result

s = "8*5-2+(10-(8*5+6)/10+5)+6*(3-2)+8*9-4"
ret = bracket_rules(s)
print(ret)#122.4

 

 
posted @ 2018-12-09 08:47  Charlie大夫  阅读(1876)  评论(0编辑  收藏  举报