zoukankan      html  css  js  c++  java
  • python使用re模块实现计算器

    import re
    
    #乘除运算处理,可以处理不含括号的加减和乘除函数(只处理乘除)
    def multi_and_divi(arg):
        #传入参数为列表,如:['3*2-1*9/3',0]
        val = arg[0]
        # 对字符串进行乘除匹配:如3*2-1*9/3,就匹配:3*2
        mch = re.search('d+.?d*[*/]+[+-]?d+.?d*', val)
        if not mch:    #mch为空,没有匹配
            return
        # 将匹配到的内容保存在content中
        content = re.search('d+.?d*[*/]+[+-]?d+.?d*',val).group()
        #print('>>>>>>>>',content)
        # 对匹配到的内容进行*、/判断,然后进行相应的计算,如2*3,先分割后计算
        if len(content.split('*')) > 1:
            n1,n2 = content.split('*')
            value = float(n1)*float(n2)
        elif len(content.split('/')) > 1:
            n1,n2 = content.split('/')
            value = round(float(n1)/float(n2),8)
        # 取出匹配内容两头的内容:before,after
        before,after = re.split('d+.?d*[*/]+[+-]?d+.?d*',val,1)
        # 拼接成新的字符串
        new_str = "%s%s%s" % (before, value, after)
        # 把new_str赋值到arg[0]中
        arg[0] = new_str
        #print(arg)
        # 再递归进行乘除计算
        multi_and_divi(arg)
    
    #multi_and_divi(['-40/-5-4*+2+2*-3+3*+3',0])
    #处理后的结果:['--8.0-8.0+-6.0+9.0', 0]
    
    #加减运算处理
    def add_and_substr(arg):
        #arg = ['--8.0-8.0+-6.0+9.0', 0]
        # 对传进来的arg[0]表达式进行第1次处理,将表达式中的++--变成+,+-、-+变成-,处理完成以后就直接break
        while True:
            if arg[0].__contains__('++') or arg[0].__contains__('--') or arg[0].__contains__('-+') or arg[0].__contains__('+-'):
                arg[0] = arg[0].replace('++','+')
                arg[0] = arg[0].replace('--','+')
                arg[0] = arg[0].replace('+-','-')
                arg[0] = arg[0].replace('-+','-')
            else:
                break
    
        # 对传进来的arg[0]表达式进行第2次处理,提取首位为“-”,并将提取的次数保存在arg[1]中
        # 并且每提取1次:将表达式中的"+"替换成"-"."-"替换成"+",然后取arg[0]表达式字符串中第1到最后1位即可赋给arg[0]
        #如:-8-10+19-4 = -(8+10-19+4)
        if arg[0].startswith('-'):
            arg[1] += 1
            arg[0] = arg[0].replace('-', '&')   #&8.0&10.0&6.0+9.0
            arg[0] = arg[0].replace('+', '-')   #&8.0&10.0&6.0-9.0
            arg[0] = arg[0].replace('&', '+')   #+8.0+10.0+6.0-9.0
            arg[0] = arg[0][1:]
        value = arg[0]
    
        # 对字符串value进行匹配,匹配加或减两边的内容,如1+2-3,就匹配1+2
        mch = re.search('d+.?d*[+-]+d+.?d*',value)
        if not mch:
            return
        content = re.search('d+.?d*[+-]+d+.?d*',value).group()
        if len(content.split('+')) > 1:
            n1,n2 = content.split('+')
            get_value = float(n1)+float(n2)
        else:
            n1,n2 = content.split('-')
            get_value = float(n1)-float(n2)
        # 取出匹配内容两头的内容:before,after
        before, after = re.split('d+.?d*[+-]+d+.?d*', arg[0], 1)
        # 拼接成新的字符串
        new_str = "%s%s%s" % (before, get_value, after)
        # 把new_str赋值到arg[0]中
        arg[0] = new_str
        #print(arg)
        add_and_substr(arg)
    
    #add_and_substr(['-8.0-10.0+-6.0+9.0', 0])
    
    #计算函数
    def compute(sr):
        #传入需要计算的函数,如:'(-40/5-4*2+2*-3+3*3)'
        #去掉括号,组成列表
        list_str = [sr.strip('()'), 0]
        multi_and_divi(list_str)
        add_and_substr(list_str)
    
        # 判断new_str[1]是奇数还是偶数,若是奇数,表明结果为负数,否则为正数
        #注:计算加减和乘除的函数没有返回值,可以取出list_str结果,原因解释见最后实例
        count = divmod(list_str[1], 2)
        result = list_str[0]
        if count[1] == 1:
            result = float(result) * (-1)
        return result
    
    #print(compute('-40/5-4*2+2*-3+3*3'))
    
    #remv_brackets:去括号,只保留最内层函数
    def remv_brackets(sr):
        flag = True
        while flag:
            # 匹配最里层“()”及函数,如:1+2*(3/(3-2)*2),这里匹配的是(3-2)
            i = re.search('([^()]+)',sr)
            if i:
                sub_str = i.group()
                # 调用计算函数,返回值赋值给sub_res
                sub_res = compute(sub_str)
                # 将i截取的第一个括号内容替换为转化为str类型的sub_res
                sr = sr.replace(sub_str,str(sub_res))
            else:
                # 如果没有括号了,打印计算函数返回的结果
                print('结果是:',compute(sr))
                flag = False
    
    if __name__ == '__main__':
        print('-------------欢迎使用--------------')
        flag = True
        while flag:
            sr = input('请输入计算函数(q退出):')
            sr = re.sub('s*','',sr)
            symbol = re.search('[0-9q+-/*]',sr)
            #print(symbol)
            if not symbol:  #判断symbol为空
                print('输入有误')
                sr = input('请重新输入要计算的函数(q:退出):')
                sr = re.sub('s*', '', sr)
                if sr == 'q':
                    exit('感谢使用,再见')
                else:
                    remv_brackets(sr)
            else:
                if sr == 'q':
                    exit('感谢使用,再见')
                else:
                    remv_brackets(sr)
    
    #1-2*((60-30+(-40/5)*(9-2*5/3+ 7/3*99/4*2998+10*568/14)) - (-4*3)/(16-3*2) )
  • 相关阅读:
    C#综合揭秘——细说事务
    软件项目管理流程总结
    WCF揭秘——自定义绑定
    WCF揭秘——共享数据契约
    反流程升职记
    .NET基础篇——利用泛型与反射更新实体(ADO.NET Entity Framework)
    先睹为快:Visual Studio 11测试版已于2.29在微软官方网站正式发布
    .NET基础篇——分部类和分部方法
    C#综合揭秘——深入分析委托与事件
    .NET基础篇——反射的奥妙
  • 原文地址:https://www.cnblogs.com/ighuahua/p/9529105.html
Copyright © 2011-2022 走看看