问题一
str1 = re.sub("([^()])", result, str1),替换的时候会把当前到下一个)全部替换。
查看结果是因为默认多次替换原因导致
str1 = re.sub("(*[^()]*)", result, str1, count=1)
替换一次正常
问题二:
怎么精确的寻到一个-+,++,*+,/+等等的双重符号。。。像下面这样每句替换吗?
str1 = re.sub("++", "+",str1)str1 = re.sub("-+", "-",str1)str1 = re.sub("*+", "*",str1)str1 = re.sub("/+", "/",str1)NO,正则就是一个找规律的游戏,上面的句子完全可以一句替代:
str1 = re.sub('W+', re.search('W-', str1).group()[0], str1,count=1)
但是,上面有个问题遇到(3-2)+1,会把)+也给找出来,太不智能了,怎么办?
试试下面的:
str1 = re.sub('[*+/-]+', re.search('[*+/-]-', str1).group()[0], str1,count=1)
只认这四个,完美解决了)+的问题,oh yeah~
问题三:
运行整数时,程序正常,运行浮点,程序就出问题,因为多了.这个非数字字符。
问题四:
测试完美的程序,运算作业题时报错。
测试打印
-->2> 1-2*((60-30-1388360.0.88095238098+1.2.0
报错:
subtotal += float(i)ValueError: could not convert string to float: '-2*'
分析:为什么会出现乱码呢?
测试-(-5/3(8-10)+23)+33这样公式都可以,比较一下,发现了问题
题目的式子,是两个括号在一起的。。。。。。
1 - 2 ( (60-30 +(-40/5) (9-25/3 + 7 /399/42998 +10 568/14 )) - (-43)/ (16-32) )
改进后的正则:就算你有10个括号在一起,也不怕!
r"([^(+][d+W+][^()]*[W+d+][^)+])"
附代码:
#!--coding:utf-8--
import re
string = '1 - 2 ( (60-30 +(-40/5) (9-25/3 + 7 /399/42998 +10 568/14 )) - (-43)/ (16-32) )'
def result(str1, i=0):
while i < 2: # 两次,因为防止去完*- 和/-以后再次出现--/+- i += 1 str1 = re.sub("--", "+", str1) # 去括号的第一步,防止-(-1)出现,做替换 str1 = re.sub("+-", "-", str1) # 去括号的第二步,防止+(-1)出现,做替换 # print('str11-->%d>'%i, str1) # 去掉多余的加号。 while re.search('[*+/-]+', str1): str1 = re.sub('[*+/-]+', re.search('[*+/-]+', str1).group()[0], str1, count=1) # 开始[*/][-]运算 opt = re.search('d*[.d]d*[*/][-]*d*[.d]d*', str1) # 查找提取*/号和前后的数字,并作为循环条件 while opt: opt = opt.group() # 提取字符串 if re.search('[*/]-', opt): # 判断减号 sub_str = re.sub('[*/]-', re.search('[*/]', opt).group(), opt, count=1) # 去掉减号 symbol = '-' else: # 没有减号,不做处理 symbol = '' sub_str = opt arithmetic = re.search('[*/]', sub_str).group() # 提取运算符 num_list = re.search('(d*[.d]d*)[*/](d*[.d]d*)', sub_str).groups() # 提取运算符前后的数字 # 用运算结果,替换掉str1中对应的字符,重新赋值给str1 str1 = re.sub('d*[.d]d*[*/][-]*d*[.d]d*', symbol+str(eval(str(num_list[0]+arithmetic+num_list[1]))), str1, count=1) opt = re.search('d*[.d]d*[*/][-]*d*[.d]d*', str1) # 查找提取*/号和前后的数字,并作为循环条件# 上面程序处理后,成为一个只有+-的字符串,下面处理+和-if str1[0].isdigit(): # 首位是数字,添加+号,为正则准备。 str1 = '+' + str1subtotal = 0 # 初始化和值opt = re.findall('(Wd*[.d*]d*)', str1) # 带加减和数字的分组for i in opt: # 累加 subtotal += float(i)return str(subtotal) # 返回计算结果def parenthesis(str1):
str1 = re.sub(r's+', '', str1)
search = re.search(r"([^(+][d+W+][^()][W+d+][^)+])", str1) # 搜索最内层括号,并作为循环条件
while search:
str_sub = search.group()
temp = str_sub[1:-1] # 去掉括号
result_str = result(temp) # 调用算术运算函数
str1 = re.sub(r"([^(+][d+W+][^()][W+d+][^)+])", result_str, str1, count=1) # 括号内计算结果替换回去
search = re.search(r"([^(+][d+W+][^()]*[W+d+][^)+])", str1) # 搜索最内层括号
return str1
def error(str1):
try:
eval(str1)
except:
print('表达式错误!')
return True
while True:
expression = input('[Q]退出,请输入算术表达式,例如:n%sn-->>' % string).strip()
if expression.lower() == 'q':
print('退出!')
break
print('您输入的表达式是:', expression)
if error(expression):
continue
else:
print('正则-运算结果是:', result(parenthesis(expression)))
print('eval-运算结果是:', eval(expression))
input('按任意键继续...')



