利用正则制作计算器

利用正则制作计算器

核心思想:1.先考虑没有括号的式子如何进行运算,然后考虑正则匹配有括号的式子,通过逐步替换

利用正则计算:1 - 2 * ( (60-30 +(-40/5) * 20) - (-4*3)/ (16-3*2) )

# 方案1

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 #!/usr/bin/env python    # -*- coding:utf-8 -*- # author: Learning       time:2018/4/30   import re # 定义一个乘除运算函数,最终返回一个运算结果 def mul_div(cal):     if '*' in cal:         x, y = cal.split('*')         return float(x) * float(y)     if '/' in cal:         x, y = cal.split('/')         return float(x) / float(y)       # 定义一个处理加减符号的函数,这步是由于乘除运算完可能为负导致的 def proce_symbol(cal):     cal = cal.replace('++','+')     cal = cal.replace('+-''-')     cal = cal.replace('--''+')     cal = cal.replace('-+''-')     return cal   # 定义一个对内层没有括号的公式进行运算的函数,最终返回一个结果 def inner(content):     """     这步对内层的乘除进行循环处理,直到里面没有了乘除运算,全部替换成了结果     :param content:     :type content:     :return: 一个不带括号的运算式的结果     :rtype:     """     # 浮点型匹配整数和浮点数啊哥,不是整数匹配浮点数     # 最后变成这样1-2*-128.8,要注意这里的正则匹配     con = re.search(r'\d+\.?\d*[*/]\-?\d+\.?\d*', content)     while con:  # 如果当中有乘除号         con = con.group()         temp = mul_div(con)  # 得到结果         content = content.replace(con,str(temp))  # 对内层运算式进行替换         content = proce_symbol(content)         #替换计算式中的乘除运算,直到替换完,对于冲突的+-号也进行替换         return inner(content)   # 通过循环一直运算式中的乘除运算计算完     else:   # 如果没有乘除号         # 对加减进行运算处理,把他们整到列表里面,挨个进行处理计算         lis = re.findall(r'[+-]?\d+\.?\d*', content)         if len(lis)>0:             total_num = 0             for in lis:                 total_num += float(i)             return total_num         else:             return lis[0]   # 匹配最内层的括号 def pars(cal):     """     定义一个计算最内层运算的函数     :param cal:     :type cal:     :return:最能层运算     :rtype:     """     par = re.search('\(([^()]*)\)', cal)     while par:   # 如果当中有括号         content = par.group()   # (-40/5)         temp = inner(content.strip('()'))  # 去括号,并处理结果-8         cal = cal.replace(content,str(temp))         return pars(cal)     # 判断里面的运算符,可以有加减乘除     else:         ret = inner(cal) # 如果没有括号         return ret   = input('计算式:').strip() # 去除空格处理,得到1-2*((60-30+(-40/5)*20)-(-4*3)/(16-3*2)) = re.sub('\s','', a) print(pars(a))

 方案2:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import re def cal(exp):     if '*' in exp:         a,b = exp.split('*')         return str(float(a) * float(b))     elif '/' in exp:         a, b = exp.split('/')         return str(float(a) / float(b))   def format(exp):     exp = exp.replace('++',"+")     exp = exp.replace('-+',"-")     exp = exp.replace('+-',"-")     exp = exp.replace('--',"+")     return exp   def dealwith(no_bracket_exp):     # 匹配乘除法     while True:         mul_div = re.search('\d+(\.?\d+)?[*/]-?\d+(\.?\d+)?', no_bracket_exp)         if mul_div:             exp = mul_div.group()             result = cal(exp)             no_bracket_exp = no_bracket_exp.replace(exp, result, 1)  # (-8)         else:break     no_bracket_exp = format(no_bracket_exp)     # 计算加减法     lst = re.findall(r'[-+]?\d+(?:\.\d+)?', no_bracket_exp)     res = str(sum([float(i) for in lst]))     return res   # 返回一个计算完毕的字符串数据类型的 数字   def remove_bracket(s):     = s.replace(' ', '')     # 去掉空格     while True:         ret = re.search(r'\([^()]+\)', s)   # 匹配最内层的括号         if ret:      # 能匹配到括号 就先处理括号内的加减乘除             no_bracket_exp = ret.group()    # 拿到括号中的表达式             ret = dealwith(no_bracket_exp)  # 把括号中的表达式交给的dealwith             = s.replace(no_bracket_exp, ret, 1)         else:       # 不能匹配到括号 就字节处理加减乘除             ret = dealwith(s)  # 把表达式交给的dealwith             return ret   = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )' print(remove_bracket(s))

 和方案二一样:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 = '1 - 2 * ( (60-30 +(-40/5) * 20) - (-4*3)/ (16-3*2) )' import re new_a = re.sub(' ','',a)  # 去括号处理 def proce_symbol(cal):  # 去重复加减号     if '++' in cal:cal = cal.replace('++','+')     if '+-' in cal:cal = cal.replace('+-''-')     if '--' in cal:cal = cal.replace('--''+')     if '-+' in cal:cal = cal.replace('-+''-')     return cal def mul_div(famula):     if '*' in famula:         num1, num2 = famula.split('*')         total = str(float(num1) * float(num2))         return total     if '/' in famula:         num1, num2 = famula.split('/')         total = str(float(num1) / float(num2))         return total def total(famula):     while True:         if '*' or '/' in famula:             num = re.search(r'\d+(\.?\d+)?[*/]\-?\d+(\.?\d+)?',famula)             if num:                 num = num.group()                 nums = mul_div(num)                 famula = famula.replace(num, nums, 1)                 famula = proce_symbol(famula)            # 如果算式中剩下加减运算             else:                 lis = re.findall(r'[-]?\d+(?:\.?\d+)?',famula)                 sums = sum([float(i) for in lis])                 return sums def bras(famu):     while True:         bra = re.search('\([^()]+\)',famu)  # 获取括号内的内容         if bra:             bra = bra.group()             ret = total(bra)             famu = famu.replace(bra,str(ret),1)             = proce_symbol(famu)             return bras(s)         else:             = proce_symbol(famu)             ret = total(s)             return ret print(bras(new_a))   
上一篇:Java时间处理 Date Calendar SimpleDateFormat的运算


下一篇:获取指定月份前的第一天和最后一天