zoukankan      html  css  js  c++  java
  • 正则计算器版中版之最后一版!

    作业要求是用正则编写一个计算器,可以计算长公司的计算器


    1
    # # coding=utf-8 2 # 1,开始入口,写一个formula,直接调用运算方法calc() 3 # 2,首先要去括号,先调用一个while循环的方法,正则方法找出最里层的括号,然后再str方法去括号,将结果进行乘除法计算 4 # 3,乘除法计算,这个乘除法要在上边的while循环里边进行,运费处理掉括号后的formula 5 # 4,先用正则分割的方法,用加减号分割,然后进行去分母去负号。 6 # 5,分母去负号方法:新建一个列表,循环老列表的值有序号,如果最后一个字母是*/,就将他与他后边的数字相‘连’,为了相连,前边要进行str方法。 7 # 把其他的含有*/的字符串,都放到新列表里,这样就形成了一个只有乘除法的列表,且分母可以是负数。返回这个新的列表 8 9 # 6,循环这个列表,把每个元素单独计算,先用split方法进行分割,再用finall方法,找出运算符。 10 # 7,循环分割的元素列表,声明一个运算结果,把第一个元素赋值给第一个结果,然后进行后边的运算,如果运算符是乘号,就进行乘法运算。 11 # 8,将运算结果替换运算公式。进行加减运算。 12 # 9.进行加减运算之前,先把所有运算符进行替换。替换后用+—进行分割,在找出所有加减号 13 # 10,跟乘法一样,先声明一个结果为空,然后如果不为空就进行运算,为空就赋值。运算过程出现加号就加,最后输出结果 14 import re 15 def jiajian(formula): 16 print(formula,'未进行加减号替换运算符的formula') 17 formula=formula.replace('--','+') 18 formula=formula.replace('+-','-') 19 formula=formula.replace('-+','-') 20 formula=formula.replace('++','+') 21 formula=formula.replace("- -", "+") 22 print(formula,'这里把加减号进行替换后的formula') 23 24 sub_yuansu_list = re.split('[+-]', formula) 25 sub_yunsuanfu_list = re.findall('[+-]', formula) 26 print("元素列表与运算符列表",sub_yuansu_list,sub_yunsuanfu_list) 27 # if sub_yuansu_list[0]=='': 28 # sub_yuansu_list[0]=='0' 29 30 print('!!!!!!!!!!!!!!!!!!!!!!!!!!!') 31 if sub_yuansu_list[0] == '': 32 sub_yuansu_list.remove('') 33 sub_yuansu_list.insert(0, '0') 34 print(sub_yuansu_list) 35 res=None 36 for index,i in enumerate(sub_yuansu_list): 37 if res: 38 if sub_yunsuanfu_list[index-1]=='-': #这里要想清楚,因为这里至少是第二次,第二次-1,那么就是元素列表index的第一次 39 res -= float(i) 40 else: 41 res += float(i) 42 else: 43 res=float(i) 44 print('33[31;1m[结果^^^%s]33[0m' %res,'完成加减法运算后的结果') 45 return res 46 47 48 def delet_fuhao_fengmu(formula): 49 new_list=[] 50 print(formula,'测试16/10') 51 for index,item in enumerate(formula): 52 53 if item.strip().endswith('*')or item.strip().endswith('/'): 54 new_list.append('%s-%s'%(formula[index],formula[index+1])) 55 elif '*' in item or '/' in item: 56 57 new_list.append(item) 58 print(new_list) 59 print(new_list,'这里是拼接分母后的列表,保留了需要进行乘法运算的元素') 60 return new_list 61 62 63 64 def chengchu(formula): 65 print('运算',formula) 66 sub_fengge_formula=re.split('[+-]',formula) #用加减号分割 67 print(sub_fengge_formula,'乘法接口还没进入del符号') 68 sub_fengge_formula = delet_fuhao_fengmu(sub_fengge_formula) 69 for index,item in enumerate(sub_fengge_formula): 70 sub_yuansu_list = re.split('[*/]',item) 71 sub_yunsuanfu_list = re.findall('[*/]',item) 72 print('乘除里打印两个列表',sub_yuansu_list,sub_yunsuanfu_list) 73 sub_res =None 74 for index,i in enumerate(sub_yuansu_list): 75 if sub_res: 76 if sub_yunsuanfu_list[index-1]=='*': 77 sub_res *= float(i) 78 else: 79 sub_res /= float(i) 80 else: 81 sub_res=float(i) 82 print('33[31;1m[%s]=33[0m'%item,sub_res,'这是完成乘法运算的结果') 83 84 formula=formula.replace(item,str(sub_res)) 85 print('33[31;1m[%s]结果33[0m'%formula,'这是在乘法里把结果替换为最准值') 86 res_zuihou=jiajian(formula) 87 88 return res_zuihou 89 90 91 def calc(formula): 92 calc_flage = True 93 while calc_flage: 94 95 m=re.search('([^()]+)',formula) 96 97 if m: 98 print(m.group(),'正则出最里边的括号') 99 sub_formula = m.group().strip('()') 100 print('去括号后', sub_formula) 101 sub_res = chengchu(sub_formula) 102 print(sub_res,'完成一次运算后的值') 103 104 formula=formula.replace(m.group(),str(sub_res)) 105 print(formula,'完成替换后的值') 106 else: 107 print('33[41;1m----没拓号了...---33[0m') 108 109 print(' 33[42;1m最终结果:33[0m', chengchu(formula)) 110 calc_flage = False # 代表公式里的拓号已经都被剥除啦 111 112 113 114 115 if __name__ == '__main__': 116 formula='1-2*(60-30+ (-40.0/5*(9-2*5/-3+7/3*99/4*2998+10*568/14)))-(-4*3)/(16-3*2)' 117 res=calc(formula) 118 119 120 print('eval',eval(formula))

    这里罗列下我出现的问题

     1 #如果formula传过去的时候是单独一个负数,如x,而我是用+—号进行分割的,分割完会出现第一个元素列表是空的情况,是空的情况如a
     2 #这时候必须把第一个元素变成float格式的,否则无法就行后边的运算,但是常规方法将0赋值不行,必须先删除,在插入。
     3 x='-1388420.3809523813'
     4 a=['', '1388420.3809523813']
     5 b=['-']
     6 if a[0]=='':
     7     a.remove('')
     8     a.insert(0,'0')
     9     print(a)
    10 res=None
    11 for index,i in enumerate(a):
    12     if res:
    13         if b[index-1]=='-':  #这里要想清楚,因为这里至少是第二次,第二次-1,那么就是元素列表index的第一次
    14             res -= float(i)
    15         else:
    16             res += float(i)
    17     else:
    18         res=float(i)
    19 print('33[31;1m[结果^^^%s]33[0m' %res,'完成加减法运算后的结果')
     1 #去括号这里出现了一个问题,前边教程用elif ('*' or '/') in item: 代替elif '*' in item or '/' in item:
     2 #我实际测试时发生了问题,无法正确匹配'/',但是第一次的时候开业匹配,后边去除掉所有括号后竟然不能匹配了,还不报错
     3 #所有该用elif '*' in item or '/' in item: 方法,后正常了,坑!
     4 def delet_fuhao_fengmu(formula):
     5     new_list=[]
     6     print(formula,'测试16/10')
     7     for index,item in enumerate(formula):
     8 
     9         if item.strip().endswith('*')or item.strip().endswith('/'):
    10             new_list.append('%s-%s'%(formula[index],formula[index+1]))
    11         elif '*' in item or '/' in item:
    12         #elif ('*' or '/') in item: 
    13 
    14             new_list.append(item)
    15             print(new_list)
    16     print(new_list,'这里是拼接分母后的列表,保留了需要进行乘法运算的元素')
    17     return new_list
     1 #这里也有问题,声明了一个sub_res变量,但是下边直接有if sub_res:,这里的意思是假如他存在,就执行加减法,不存在就给他赋值item,用于后边的运算,这里不太通顺,但是能用。
      但是这里if的值应该是个布尔值,现在这么用不通顺。我选择得过且过了。
    2 sub_res =None 3 for index,i in enumerate(sub_yuansu_list): 4 if sub_res: 5 if sub_yunsuanfu_list[index-1]=='*': 6 sub_res *= float(i) 7 else: 8 sub_res /= float(i) 9 else: 10 sub_res=float(i) 11 print('33[31;1m[%s]=33[0m'%item,sub_res,'这是完成乘法运算的结果')

    一些测试代码

     1 import re
     2 # a='qiangql abc   ccccabcabc'
     3 #
     4 # b=re.search('abc{2}',a)
     5 # c=re.search('(abc){2}',a)
     6 # print(b,c)
     7 # d=re.search('|','331|')
     8 # print(d)
     9 #
    10 # w=re.sub('s','',a)
    11 # print(w)
    12 #如果formula传过去的时候是单独一个负数,如x,而我是用+—号进行分割的,分割完会出现第一个元素列表是空的情况,是空的情况如a
    13 #这时候必须把第一个元素变成float格式的,否则无法就行后边的运算,但是常规方法将0赋值不行必须先删除,在插入。
    14 x='-1388420.3809523813'
    15 a=['', '1388420.3809523813']
    16 b=['-']
    17 if a[0]=='':
    18     a.remove('')
    19     a.insert(0,'0')
    20     print(a)
    21 res=None
    22 for index,i in enumerate(a):
    23     if res:
    24         if b[index-1]=='-':  #这里要想清楚,因为这里至少是第二次,第二次-1,那么就是元素列表index的第一次
    25             res -= float(i)
    26         else:
    27             res += float(i)
    28     else:
    29         res=float(i)
    30 print('33[31;1m[结果^^^%s]33[0m' %res,'完成加减法运算后的结果')
    31 
    32 # a='1-2*1388450.3809523813-12.5/10.6'
    33 # a_yuansu=re.split('[+-]',a)
    34 # a_yunsaunfu=re.findall('[*/]',a)
    35 # print(a_yuansu,a_yunsaunfu)
    36 # res=None
    37 # for index,i in enumerate(a_yuansu):
    38 #     if res:
    39 #        if a_yunsaunfu[index-1]=='*':
    40 #            res *= res
    41 #        else:
    42 #            res /= res
    43 #     else:
    44 #         res=float(i)
    45 #     print(i,res)
    46 #去括号这里出现了一个问题,前边教程用elif ('*' or '/') in item: 代替elif '*' in item or '/' in item:
    47 #我实际测试时发生了问题,无法正确匹配'/',但是第一次的时候开业匹配,后边去除掉所有括号后竟然不能匹配了,还不报错
    48 #所有该用elif '*' in item or '/' in item: 方法,后正常了,坑!
    49 def delet_fuhao_fengmu(formula):
    50     new_list=[]
    51     print(formula,'测试16/10')
    52     for index,item in enumerate(formula):
    53 
    54         if item.strip().endswith('*')or item.strip().endswith('/'):
    55             new_list.append('%s-%s'%(formula[index],formula[index+1]))
    56         elif '*' in item or '/' in item:
    57         #elif ('*' or '/') in item:
    58 
    59             new_list.append(item)
    60             print(new_list)
    61     print(new_list,'这里是拼接分母后的列表,保留了需要进行乘法运算的元素')
    62     return new_list
    测试

    运算结果

      1 C:UsersqiangqlAppDataLocalProgramsPythonPython36-32python.exe C:/Users/qiangql/PycharmProjects/untitled1/计算器3.py
      2 (9-2*5/-3+7/3*99/4*2998+10*568/14) 正则出最里边的括号
      3 去括号后 9-2*5/-3+7/3*99/4*2998+10*568/14
      4 运算 9-2*5/-3+7/3*99/4*2998+10*568/14
      5 ['9', '2*5/', '3', '7/3*99/4*2998', '10*568/14'] 乘法接口还没进入del符号
      6 ['9', '2*5/', '3', '7/3*99/4*2998', '10*568/14'] 测试16/10
      7 ['2*5/-3', '7/3*99/4*2998']
      8 ['2*5/-3', '7/3*99/4*2998', '10*568/14']
      9 ['2*5/-3', '7/3*99/4*2998', '10*568/14'] 这里是拼接分母后的列表,保留了需要进行乘法运算的元素
     10 乘除里打印两个列表 ['2', '5', '-3'] ['*', '/']
     11 [2*5/-3]= -3.3333333333333335 这是完成乘法运算的结果
     12 乘除里打印两个列表 ['7', '3', '99', '4', '2998'] ['/', '*', '/', '*']
     13 [7/3*99/4*2998]= 173134.50000000003 这是完成乘法运算的结果
     14 乘除里打印两个列表 ['10', '568', '14'] ['*', '/']
     15 [10*568/14]= 405.7142857142857 这是完成乘法运算的结果
     16 [9--3.3333333333333335+173134.50000000003+405.7142857142857]结果 这是在乘法里把结果替换为最准值
     17 9--3.3333333333333335+173134.50000000003+405.7142857142857 未进行加减号替换运算符的formula
     18 9+3.3333333333333335+173134.50000000003+405.7142857142857 这里把加减号进行替换后的formula
     19 元素列表与运算符列表 ['9', '3.3333333333333335', '173134.50000000003', '405.7142857142857'] ['+', '+', '+']
     20 !!!!!!!!!!!!!!!!!!!!!!!!!!!
     21 [结果^^^173552.54761904766] 完成加减法运算后的结果
     22 173552.54761904766 完成一次运算后的值
     23 1-2*(60-30+ (-40.0/5*173552.54761904766))-(-4*3)/(16-3*2) 完成替换后的值
     24 (-40.0/5*173552.54761904766) 正则出最里边的括号
     25 去括号后 -40.0/5*173552.54761904766
     26 运算 -40.0/5*173552.54761904766
     27 ['', '40.0/5*173552.54761904766'] 乘法接口还没进入del符号
     28 ['', '40.0/5*173552.54761904766'] 测试16/10
     29 ['40.0/5*173552.54761904766']
     30 ['40.0/5*173552.54761904766'] 这里是拼接分母后的列表,保留了需要进行乘法运算的元素
     31 乘除里打印两个列表 ['40.0', '5', '173552.54761904766'] ['/', '*']
     32 [40.0/5*173552.54761904766]= 1388420.3809523813 这是完成乘法运算的结果
     33 [-1388420.3809523813]结果 这是在乘法里把结果替换为最准值
     34 -1388420.3809523813 未进行加减号替换运算符的formula
     35 -1388420.3809523813 这里把加减号进行替换后的formula
     36 元素列表与运算符列表 ['', '1388420.3809523813'] ['-']
     37 !!!!!!!!!!!!!!!!!!!!!!!!!!!
     38 ['0', '1388420.3809523813']
     39 [结果^^^1388420.3809523813] 完成加减法运算后的结果
     40 1388420.3809523813 完成一次运算后的值
     41 1-2*(60-30+ 1388420.3809523813)-(-4*3)/(16-3*2) 完成替换后的值
     42 (60-30+ 1388420.3809523813) 正则出最里边的括号
     43 去括号后 60-30+ 1388420.3809523813
     44 运算 60-30+ 1388420.3809523813
     45 ['60', '30', ' 1388420.3809523813'] 乘法接口还没进入del符号
     46 ['60', '30', ' 1388420.3809523813'] 测试16/10
     47 [] 这里是拼接分母后的列表,保留了需要进行乘法运算的元素
     48 [60-30+ 1388420.3809523813]结果 这是在乘法里把结果替换为最准值
     49 60-30+ 1388420.3809523813 未进行加减号替换运算符的formula
     50 60-30+ 1388420.3809523813 这里把加减号进行替换后的formula
     51 元素列表与运算符列表 ['60', '30', ' 1388420.3809523813'] ['-', '+']
     52 !!!!!!!!!!!!!!!!!!!!!!!!!!!
     53 [结果^^^1388450.3809523813] 完成加减法运算后的结果
     54 1388450.3809523813 完成一次运算后的值
     55 1-2*1388450.3809523813-(-4*3)/(16-3*2) 完成替换后的值
     56 (-4*3) 正则出最里边的括号
     57 去括号后 -4*3
     58 运算 -4*3
     59 ['', '4*3'] 乘法接口还没进入del符号
     60 ['', '4*3'] 测试16/10
     61 ['4*3']
     62 ['4*3'] 这里是拼接分母后的列表,保留了需要进行乘法运算的元素
     63 乘除里打印两个列表 ['4', '3'] ['*']
     64 [4*3]= 12.0 这是完成乘法运算的结果
     65 [-12.0]结果 这是在乘法里把结果替换为最准值
     66 -12.0 未进行加减号替换运算符的formula
     67 -12.0 这里把加减号进行替换后的formula
     68 元素列表与运算符列表 ['', '12.0'] ['-']
     69 !!!!!!!!!!!!!!!!!!!!!!!!!!!
     70 ['0', '12.0']
     71 [结果^^^12.0] 完成加减法运算后的结果
     72 12.0 完成一次运算后的值
     73 1-2*1388450.3809523813-12.0/(16-3*2) 完成替换后的值
     74 (16-3*2) 正则出最里边的括号
     75 去括号后 16-3*2
     76 运算 16-3*2
     77 ['16', '3*2'] 乘法接口还没进入del符号
     78 ['16', '3*2'] 测试16/10
     79 ['3*2']
     80 ['3*2'] 这里是拼接分母后的列表,保留了需要进行乘法运算的元素
     81 乘除里打印两个列表 ['3', '2'] ['*']
     82 [3*2]= 6.0 这是完成乘法运算的结果
     83 [16-6.0]结果 这是在乘法里把结果替换为最准值
     84 16-6.0 未进行加减号替换运算符的formula
     85 16-6.0 这里把加减号进行替换后的formula
     86 元素列表与运算符列表 ['16', '6.0'] ['-']
     87 !!!!!!!!!!!!!!!!!!!!!!!!!!!
     88 [结果^^^10.0] 完成加减法运算后的结果
     89 10.0 完成一次运算后的值
     90 1-2*1388450.3809523813-12.0/10.0 完成替换后的值
     91 ----没拓号了...---
     92 运算 1-2*1388450.3809523813-12.0/10.0
     93 ['1', '2*1388450.3809523813', '12.0/10.0'] 乘法接口还没进入del符号
     94 ['1', '2*1388450.3809523813', '12.0/10.0'] 测试16/10
     95 ['2*1388450.3809523813']
     96 ['2*1388450.3809523813', '12.0/10.0']
     97 ['2*1388450.3809523813', '12.0/10.0'] 这里是拼接分母后的列表,保留了需要进行乘法运算的元素
     98 乘除里打印两个列表 ['2', '1388450.3809523813'] ['*']
     99 [2*1388450.3809523813]= 2776900.7619047626 这是完成乘法运算的结果
    100 乘除里打印两个列表 ['12.0', '10.0'] ['/']
    101 [12.0/10.0]= 1.2 这是完成乘法运算的结果
    102 [1-2776900.7619047626-1.2]结果 这是在乘法里把结果替换为最准值
    103 1-2776900.7619047626-1.2 未进行加减号替换运算符的formula
    104 1-2776900.7619047626-1.2 这里把加减号进行替换后的formula
    105 元素列表与运算符列表 ['1', '2776900.7619047626', '1.2'] ['-', '-']
    106 !!!!!!!!!!!!!!!!!!!!!!!!!!!
    107 [结果^^^-2776900.961904763] 完成加减法运算后的结果
    108 
    109 
    110 最终结果: -2776900.961904763
    111 eval 2776782.961904763
    112 
    113 Process finished with exit code 0

  • 相关阅读:
    WorkFlow
    自己写的一个多线程的consumer 和 producter 模式
    Visual Studio进行Web性能测试
    基元线程同步——内核模式构造
    系统架构师
    《构建高性能的web站点》读书笔记缓存
    python中的代码对象
    python web框架互相融合, Pyramid或取代Django
    海量数据处理专题
    Django框架学习Forms篇
  • 原文地址:https://www.cnblogs.com/PYlog/p/8944724.html
Copyright © 2011-2022 走看看