zoukankan      html  css  js  c++  java
  • Python 3.x--使用re模块,实现计算器运算实例

    要求:使用re模块,通过正则表达式,实现计算器运算功能。

    思路:1、匹配函数中最内层的括号,提取函数使用re.search,先计算乘除,后计算加减,注意针对正负号的处理,使用re.split,可以截取函数前后的部分,重新拼接结果。

       2、加减、乘除及去括号单独写函数调用

    具体代码:

      1 import re
      2 
      3 #乘除运算处理,可以处理不含括号的加减和乘除函数(只处理乘除)
      4 def multi_and_divi(arg):
      5     #传入参数为列表,如:['3*2-1*9/3',0]
      6     val = arg[0]
      7     # 对字符串进行乘除匹配:如3*2-1*9/3,就匹配:3*2
      8     mch = re.search('d+.?d*[*/]+[+-]?d+.?d*', val)
      9     if not mch:    #mch为空,没有匹配
     10         return
     11     # 将匹配到的内容保存在content中
     12     content = re.search('d+.?d*[*/]+[+-]?d+.?d*',val).group()
     13     #print('>>>>>>>>',content)
     14     # 对匹配到的内容进行*、/判断,然后进行相应的计算,如2*3,先分割后计算
     15     if len(content.split('*')) > 1:
     16         n1,n2 = content.split('*')
     17         value = float(n1)*float(n2)
     18     elif len(content.split('/')) > 1:
     19         n1,n2 = content.split('/')
     20         value = round(float(n1)/float(n2),8)
     21     # 取出匹配内容两头的内容:before,after
     22     before,after = re.split('d+.?d*[*/]+[+-]?d+.?d*',val,1)
     23     # 拼接成新的字符串
     24     new_str = "%s%s%s" % (before, value, after)
     25     # 把new_str赋值到arg[0]中
     26     arg[0] = new_str
     27     #print(arg)
     28     # 再递归进行乘除计算
     29     multi_and_divi(arg)
     30 
     31 #multi_and_divi(['-40/-5-4*+2+2*-3+3*+3',0])
     32 #处理后的结果:['--8.0-8.0+-6.0+9.0', 0]
     33 
     34 #加减运算处理
     35 def add_and_substr(arg):
     36     #arg = ['--8.0-8.0+-6.0+9.0', 0]
     37     # 对传进来的arg[0]表达式进行第1次处理,将表达式中的++--变成+,+-、-+变成-,处理完成以后就直接break
     38     while True:
     39         if arg[0].__contains__('++') or arg[0].__contains__('--') or arg[0].__contains__('-+') or arg[0].__contains__('+-'):
     40             arg[0] = arg[0].replace('++','+')
     41             arg[0] = arg[0].replace('--','+')
     42             arg[0] = arg[0].replace('+-','-')
     43             arg[0] = arg[0].replace('-+','-')
     44         else:
     45             break
     46 
     47     # 对传进来的arg[0]表达式进行第2次处理,提取首位为“-”,并将提取的次数保存在arg[1]中
     48     # 并且每提取1次:将表达式中的"+"替换成"-"."-"替换成"+",然后取arg[0]表达式字符串中第1到最后1位即可赋给arg[0]
     49     #如:-8-10+19-4 = -(8+10-19+4)
     50     if arg[0].startswith('-'):
     51         arg[1] += 1
     52         arg[0] = arg[0].replace('-', '&')   #&8.0&10.0&6.0+9.0
     53         arg[0] = arg[0].replace('+', '-')   #&8.0&10.0&6.0-9.0
     54         arg[0] = arg[0].replace('&', '+')   #+8.0+10.0+6.0-9.0
     55         arg[0] = arg[0][1:]
     56     value = arg[0]
     57 
     58     # 对字符串value进行匹配,匹配加或减两边的内容,如1+2-3,就匹配1+2
     59     mch = re.search('d+.?d*[+-]+d+.?d*',value)
     60     if not mch:
     61         return
     62     content = re.search('d+.?d*[+-]+d+.?d*',value).group()
     63     if len(content.split('+')) > 1:
     64         n1,n2 = content.split('+')
     65         get_value = float(n1)+float(n2)
     66     else:
     67         n1,n2 = content.split('-')
     68         get_value = float(n1)-float(n2)
     69     # 取出匹配内容两头的内容:before,after
     70     before, after = re.split('d+.?d*[+-]+d+.?d*', arg[0], 1)
     71     # 拼接成新的字符串
     72     new_str = "%s%s%s" % (before, get_value, after)
     73     # 把new_str赋值到arg[0]中
     74     arg[0] = new_str
     75     #print(arg)
     76     add_and_substr(arg)
     77 
     78 #add_and_substr(['-8.0-10.0+-6.0+9.0', 0])
     79 
     80 #计算函数
     81 def compute(sr):
     82     #传入需要计算的函数,如:'(-40/5-4*2+2*-3+3*3)'
     83     #去掉括号,组成列表
     84     list_str = [sr.strip('()'), 0]
     85     multi_and_divi(list_str)
     86     add_and_substr(list_str)
     87 
     88     # 判断new_str[1]是奇数还是偶数,若是奇数,表明结果为负数,否则为正数
     89     #注:计算加减和乘除的函数没有返回值,可以取出list_str结果,原因解释见最后实例
     90     count = divmod(list_str[1], 2)
     91     result = list_str[0]
     92     if count[1] == 1:
     93         result = float(result) * (-1)
     94     return result
     95 
     96 #print(compute('-40/5-4*2+2*-3+3*3'))
     97 
     98 #remv_brackets:去括号,只保留最内层函数
     99 def remv_brackets(sr):
    100     flag = True
    101     while flag:
    102         # 匹配最里层“()”及函数,如:1+2*(3/(3-2)*2),这里匹配的是(3-2)
    103         i = re.search('([^()]+)',sr)
    104         if i:
    105             sub_str = i.group()
    106             # 调用计算函数,返回值赋值给sub_res
    107             sub_res = compute(sub_str)
    108             # 将i截取的第一个括号内容替换为转化为str类型的sub_res
    109             sr = sr.replace(sub_str,str(sub_res))
    110         else:
    111             # 如果没有括号了,打印计算函数返回的结果
    112             print('结果是:',compute(sr))
    113             flag = False
    114 
    115 if __name__ == '__main__':
    116     print('-------------欢迎使用--------------')
    117     flag = True
    118     while flag:
    119         sr = input('请输入计算函数(q退出):')
    120         sr = re.sub('s*','',sr)
    121         symbol = re.search('[0-9q+-/*]',sr)
    122         #print(symbol)
    123         if not symbol:  #判断symbol为空
    124             print('输入有误')
    125             sr = input('请重新输入要计算的函数(q:退出):')
    126             sr = re.sub('s*', '', sr)
    127             if sr == 'q':
    128                 exit('感谢使用,再见')
    129             else:
    130                 remv_brackets(sr)
    131         else:
    132             if sr == 'q':
    133                 exit('感谢使用,再见')
    134             else:
    135                 remv_brackets(sr)
    136 
    137 #1-2*((60-30+(-40/5)*(9-2*5/3+ 7/3*99/4*2998+10*568/14)) - (-4*3)/(16-3*2) )

    运行结果:

    因为list是可变对象,l1传入func时,list1与l1指向的是同一个list,list1执行append,就是l1和list1指向的这同一个list执行了append,然后list1又重新指向了一个新的list,此时不会对原list产生影响。

  • 相关阅读:
    领域建模
    中科院
    开放搜索服务OpenSearch
    GUIForDebug
    java: org.luaj.vm2.LuaError:XXX module not found lua脚本初始化出错(转)
    new TimerTask(robot)(转)
    lua-TestMore(转)
    Lua 数据库访问(转)
    推荐谈论高并发柱
    查看文章strncpy()功能更好的文章
  • 原文地址:https://www.cnblogs.com/rainowl-ymj/p/7129144.html
Copyright © 2011-2022 走看看