第一次在博客发帖。
看的网课要编辑一个计算器,要实现能运算负数和小括号
左思右想,刚学的正则模块。寻思着编辑一下。第一次的思路是:先做一个函数,实现四则运算。用正则匹配出符号和数字
1 def size(ch): #定义一个基础的四则运算用于基础计算 2 list_num=re.split('[-,+,*,/]',ch) #定义一个对象接收所有运算的数字 3 list_sym=re.findall('+|-|*|/',ch)#定义一个对象接收所有运算的符号 4 num=0 5 list_del=[] 6 for i in list_sym: 7 if i=='/'or i=='*':#判断有无乘除, 8 if i=='*':#有的话顺序执行乘除 9 list_num[num]=str(int(float(list_num[num]))*int(float(list_num[num+1]))) 10 elif i=='/': 11 list_num[num]=str(int(float(list_num[num]))/int(float(list_num[num+1]))) 12 del list_num[num+1]#删除后面一个元素 13 list_del.append(num)#存储需要删除的符号的位置 14 num-=1#与上面和下面相对应,删除一个元素num减少1,使得删除符号的位置能刚好对应 15 num+=1 16 for i in list_del: 17 del list_sym[i] 18 del list_del #移除空列表 19 num=0 20 for i in list_sym: 21 if i =='+' or i =='-': 22 if i=='+':#有的话顺序执行加减 23 list_num[num]=str(int(float(list_num[num]))+int(float(list_num[num+1]))) 24 elif i=='-': 25 list_num[num]=str(int(float(list_num[num]))-int(float(list_num[num+1]))) 26 del list_num[num+1]#删除后面一个元素 27 num-=1 28 num+=1 29 del list_sym #移除符号列表 30 return list_num[0] #返回计算好的值 #不能有负数的低端版
但是,这个有一个缺点,就是不能计算负号,这是一个头疼的问题。
然后就有了改进版,直接用一个列表接收各种数据符号,而且,这里面只考虑乘除,不考虑加减,加在后面直接用遍历列表做,减直接跟着数据进行乘除。
1 def size(ch): #定义一个基础的四则运算用于基础计算 2 ch=re.sub('--','+',ch)#去除两个减号相连 3 list_num=re.findall('(d+|-d+|/|*)',ch) #定义一个对象接收所有运算对象 4 num=0 5 list_del=[]#基于四则运算的基本原则,不管加减只论乘除,最后结果在列表中相加,减号直接当成数据直接处理 6 for i in list_num: 7 if i=='/'or i=='*':#判断有无乘除 8 if i=='*':#有的话顺序执行乘除 9 list_num[num+1]=str(int(float(list_num[num-1]))*int(float(list_num[num+1]))) 10 elif i=='/': 11 list_num[num+1]=str(int(float(list_num[num-1]))/int(float(list_num[num+1]))) 12 list_del.append(num-1) 13 list_del.append(num)#记录需要删除的前面两个元素 14 num+=1 15 m=0 16 for i in list_del: 17 del list_num[i-m] 18 m+=1#删除时需要自减,不然会重复删除大的数据 19 del list_del #移除空列表 20 sum=0 21 for j in list_num: 22 sum+=int(float(j)) 23 return sum #返回计算好的值
然后要考虑的是匹配括号里面的内容。
这该怎么匹配呢,要想匹配出内层括号,换个思路就是要让括号内没有其他括号
date_m=re.search('([^()]+)',date).group()#正则匹配最内层括号及内层数据
还有各种各样的问题要考虑,在这列举两个,去除输入的字符串中的空格,把+和-相连改成-
date=re.sub('s*','',date)#去除输入字符串中的空格 date=re.sub('+-|-+','-',date)#去除+-符号相连
完整代码
1 import re 2 def size(ch): #定义一个基础的四则运算用于基础计算 3 ch=re.sub('--','+',ch)#去除两个减号相连 4 list_num=re.findall('(d+|-d+|/|*)',ch) #定义一个对象接收所有运算对象 5 num=0 6 list_del=[]#基于四则运算的基本原则,不管加减只论乘除,最后结果在列表中相加,减号直接当成数据直接处理 7 for i in list_num: 8 if i=='/'or i=='*':#判断有无乘除 9 if i=='*':#有的话顺序执行乘除 10 list_num[num+1]=str(int(float(list_num[num-1]))*int(float(list_num[num+1]))) 11 elif i=='/': 12 list_num[num+1]=str(int(float(list_num[num-1]))/int(float(list_num[num+1]))) 13 list_del.append(num-1) 14 list_del.append(num)#记录需要删除的前面两个元素 15 num+=1 16 m=0 17 for i in list_del: 18 del list_num[i-m] 19 m+=1#删除时需要自减,不然会重复删除大的数据 20 del list_del #移除空列表 21 sum=0 22 for j in list_num: 23 sum+=int(float(j)) 24 return sum #返回计算好的值 25 while True: 26 date=input('输入计算数字的字符串:') 27 date=re.sub('s*','',date)#去除输入字符串中的空格 28 date=re.sub('+-|-+','-',date)#去除+-符号相连 29 if re.search('[a-zA-Z]',date)!=None: #匹配字母 30 print('不能输入字母') 31 else: 32 if len(re.findall('(',date))!=len(re.findall(')',date)): #求两匹配列表长度 33 print('输入的左右括号不一致') 34 else: 35 while True: 36 if re.search('(',date)!=None: 37 date_m=re.search('([^()]+)',date).group()#正则匹配最内层括号及内层数据 38 date_x=re.sub('(|)','',date_m)#正则匹配去除两边括号 39 date_n=re.sub('+','+',date_m) 40 date_n=re.sub('*','*',date_n) 41 date_n=re.sub('(','(',date_n) 42 date_n = re.sub(')', ')', date_n)#将特殊字符普通化 43 date=re.sub(date_n,str(size(date_x)),date)#将括号里面的字符计算出来并替代原来字符串 44 else: 45 print(size(date))#输出结果 46 break #退出循环 47 48 #由于不是小数型,所以输出结果有偏差。
这个代码只能计算整型,要是小数操作可能会报错或者输出有误差。