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产生影响。