• Python实例---利用正则实现计算器[参考版]


    利用正则进行运算规则的计算

    版本一:

    # import re
    #
    # ss = '1 - 2 * ((60 - 30 + (-40/5) * (9 - 2 * 5 / 3 + 7 / 3 * 99 / 4 * 2998 + 10 * 568 / 14)) - (-4 * 3) / (16 - 3 * 2))'
    #
    # print(re.search('([^(]+)', ss).group())
    #
    # def check(s):
    #     flag = True
    #     if re.findall('[a-zA-Z]', s):
    #         print('Invalid')
    #         flag = False
    #     return flag
    #
    # def check_format(s):
    #     s = s.replace(' ', '')
    #     s = s.replace('++', '+')
    #     s = s.replace('--', '+')
    #     s = s.replace('-+', '-')
    #     return s
    # # 计算乘法,除法
    # def cal_mul_div(s):  # 匹配小数,多位数字 (2+3.2*5.6)
    #     # 返回乘法的结果
    #     str1 =  re.search('d+.?d*[*/]d+.?d*', s).group()
    #     # 3.2 5.6 *进行切割
    #     x, y = re.split('[*/]', str)   #x='3.2', y='5.6'
    #     if str.find('.'):
    #         ret2 = float(x) * float(y)
    #         str(ret2)
    #     else:
    #         ret2 = int(x) * int(y)
    #         str(ret2)
    #     s.replace(str1, ret2)
    #     return s
    #
    #
    #
    #     return s  # 2 + 15
    #
    #
    # def cal_add_sub(s): # s=2+15
    #
    #
    # if check(ss):
    #     str = check_format(ss)
    #     while re.search('(', str):
    #         # 1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
    #         strs = re.search('([^(]+)', ss).group()
    #         str = cal_mul_div(str)  # 2+25
    #         s = cal_add_sub(str)    # (27)
    #
    #     else:
    #
    # else:
    #     print('no')
    #
    
    
    
    #!/usr/bin/python27
    #_*_ coding=utf-8 _*_
    
    
    '''
    该计算器思路:
        1、递归寻找表达式中只含有 数字和运算符的表达式,并计算结果
        2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数
    使用技术:
        1、正则表达式
        2、递归
    
    执行流程如下:
    ******************** 请计算表达式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) ********************
    before: ['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
    -40.0/5=-8.0
    after: ['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
    ========== 上一次计算结束 ==========
    before: ['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
    9-2*5/3+7/3*99/4*2998+10*568/14=173545.880953
    after: ['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']
    ========== 上一次计算结束 ==========
    before: ['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']
    60-30+-8.0*173545.880953=-1388337.04762
    after: ['1-2*(-1388337.04762-(-4*3)/(16-3*2))']
    ========== 上一次计算结束 ==========
    before: ['1-2*(-1388337.04762-(-4*3)/(16-3*2))']
    -4*3=-12.0
    after: ['1-2*(-1388337.04762--12.0/(16-3*2))']
    ========== 上一次计算结束 ==========
    before: ['1-2*(-1388337.04762--12.0/(16-3*2))']
    16-3*2=10.0
    after: ['1-2*(-1388337.04762--12.0/10.0)']
    ========== 上一次计算结束 ==========
    before: ['1-2*(-1388337.04762--12.0/10.0)']
    -1388337.04762--12.0/10.0=-1388335.84762
    after: ['1-2*-1388335.84762']
    ========== 上一次计算结束 ==========
    我的计算结果: 2776672.69524
    '''
    

    版本二:

    
    import re,os,sys
    
    def compute_exponent(arg):
        """ 操作指数
        :param expression:表达式
        :return:计算结果
        """
    
        val = arg[0]
        pattern = re.compile(r'd+.?d*[*]{2}[+-]?d+.?d*')
        mch = pattern.search(val)
        if not mch:
            return
        content = pattern.search(val).group()
    
        if len(content.split('**'))>1:
            n1, n2 = content.split('**')
            value = float(n1) ** float(n2)
        else:
            pass
    
        before, after = pattern.split(val, 1)
        new_str = "%s%s%s" % (before,value,after)
        arg[0] = new_str
        compute_exponent(arg)
    
    def compute_mul_div(arg):
        """ 操作乘除
        :param expression:表达式
        :return:计算结果
        """
    
        val = arg[0]
        pattern = re.compile(r'd+.?d*[*/\%//]+[+-]?d+.*d*')
        mch = pattern.search(val)
        if not mch:
            return
        content = pattern.search(val).group()
    
        if len(content.split('*'))>1:
            n1, n2 = content.split('*')
            value = float(n1) * float(n2)
        elif len(content.split('//'))>1:
            n1, n2 = content.split('//')
            value = float(n1) // float(n2)
        elif len(content.split('%'))>1:
            n1, n2 = content.split('%')
            value = float(n1) % float(n2)
        elif len(content.split('/'))>1:
            n1, n2 = content.split('/')
            value = float(n1) / float(n2)
        else:
            pass
    
        before, after = pattern.split(val, 1)
        new_str = "%s%s%s" % (before,value,after)
        arg[0] = new_str
        compute_mul_div(arg)
    
    
    def compute_add_sub(arg):
        """ 操作加减
        :param expression:表达式
        :return:计算结果
        """
        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
    
    
        if arg[0].startswith('-'):
    
            arg[1] += 1
            arg[0] = arg[0].replace('-','&')
            arg[0] = arg[0].replace('+','-')
            arg[0] = arg[0].replace('&','+')
            arg[0] = arg[0][1:]
        val = arg[0]
    
        pattern = re.compile(r'd+.?d*[+-]{1}d+.?d*')
        mch = pattern.search(val)
        if not mch:
            return
        content = pattern.search(val).group()
        if len(content.split('+'))>1:
            n1, n2 = content.split('+')
            value = float(n1) + float(n2)
        else:
            n1, n2 = content.split('-')
            value = float(n1) - float(n2)
    
        before, after = pattern.split(val, 1)
        new_str = "%s%s%s" % (before,value,after)
        arg[0] = new_str
        compute_add_sub(arg)
    
    
    def compute(expression):
        """ 操作加减乘除
        :param expression:表达式
        :return:计算结果
        """
        inp = [expression,0]
    
        # 处理表达式中的指数
        compute_exponent(inp)
    
        # 处理表达式中的乘除求余等
        compute_mul_div(inp)
    
        # 处理表达式的加减
        compute_add_sub(inp)
        if divmod(inp[1],2)[1] == 1:
            result = float(inp[0])
            result = result * -1
        else:
            result = float(inp[0])
        return result
    
    
    def exec_bracket(expression):
        """ 递归处理括号,并计算
        :param expression: 表达式
        :return:最终计算结果
        """
        pattern = re.compile(r'(([+-*/\%//**]*d+.*d*){2,})')
        # 如果表达式中已经没有括号,则直接调用负责计算的函数,将表达式结果返回,如:2*1-82+444
        #if not re.search('(([+-*/]*d+.*d*){2,})', expression):
        if not pattern.search(expression):
            final = compute(expression)
            return final
        # 获取 第一个 只含有 数字/小数 和 操作符 的括号
        # 如:
        #    ['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
        #    找出:(-40.0/5)
        content = pattern.search(expression).group()
    
    
        # 分割表达式,即:
        # 将['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
        # 分割更三部分:['1-2*((60-30+(    (-40.0/5)      *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
        before, nothing, after = pattern.split(expression, 1)
    
        print('before:',expression)
        content = content[1:len(content)-1]
    
        # 计算,提取的表示 (-40.0/5),并活的结果,即:-40.0/5=-8.0
        ret = compute(content)
    
        print('%s=%s' %( content, ret))
    
        # 将执行结果拼接,['1-2*((60-30+(      -8.0     *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
        expression = "%s%s%s" %(before, ret, after)
        print('after:',expression)
        print("="*10,'previous result is',"="*10)
    
        # 循环继续下次括号处理操作,本次携带者的是已被处理后的表达式,即:
        # ['1-2*((60-30+   -8.0  *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
    
        # 如此周而复始的操作,直到表达式中不再含有括号
        return exec_bracket(expression)
    
    
    
    # 使用 __name__ 的目的:
    #   只有执行 python index.py 时,以下代码才执行
    #   如果其他人导入该模块,以下代码不执行
    if __name__ == "__main__":
        flag = True
    
        os.system('clear')
    
        print('
    ================================================================')
        print('33[33m 欢迎使用计算器 :33[0m')
        print('
    ================================================================')
    
    
    
        while flag:
            calculate_input = input('33[32m请输入计算的表达式 | (退出:q)33[0m')
            calculate_input = re.sub('s*','',calculate_input)
            if len(calculate_input) == 0:
                continue
            elif calculate_input == 'q':
                sys.exit('退出程序')
            elif re.search('[^0-9.-+*/\%//**()]',calculate_input):
                print('33[31m 输入错误,请重新输入!!!33[0m')
            else:
                result = exec_bracket(calculate_input)
                print('the expression result is %s' % result)
    [代码来自网络,仅供学习]
     【更多参考】

    Java实例---计算器实例

  • 相关阅读:
    在Eclipse或者STS中使用SVN插件
    SVN的忽略、版本回退、版本冲突(window)
    SVN的图标集
    HTML5+NodeJs实现WebSocket即时通讯
    import和require的区别
    正则表达式 金额验证
    vue 弹窗弹窗禁止滑动的方法 看了网上很多方法 都是扯淡 直接贴上代码
    uni-app关于小程序及app端第三方微信登陆问题
    用 async/await 来处理异步
    微信小程序 子组件调用父组件方法
  • 原文地址:https://www.cnblogs.com/ftl1012/p/9383412.html
Copyright © 2020-2023  润新知