1 # s="1 - 2 * ((60 - 30 + (-40 / 5) * (9 - 2 * 5 / 3 + 7 / 3 * 99 / 4 * 2998 + 10 * 568 / 14)) - (-4 * 3) / (16 - 3 * 2))" 2 s=input("please input you number str:") 3 import re 4 s=s.replace(" ","") 5 while True: 6 a=re.search(‘\([^()]+\)‘,s) #得到带括号的一个算式。 7 if a !=None: a=a.group() 8 if a ==None: a=s 9 if len(re.findall("[\+\-]?\d+\.?\d*",a))==1: 10 print(s) 11 break 12 if "/" in a: #优先查找/法。乘除前面的符号本来就是归于数字的,所以必须带上负号。 13 b=re.search("(?P<fir>\-?\d+\.?\d*)/(?P<sec>[\+\-]?\d+\.?\d*)",a) #将算式分组,成为两个数字。调用这两个数字进行运算。 14 c=float(b.group("fir"))/float(b.group("sec")) #前面的匹配数字取负不取正,避免脱括号少减号,加+号会消加号,影响计算。 15 elif "*" in a: #其次是*法。 #而且避免连续出现三个符号,这样是为了约分。 16 b=re.search("(?P<fir>\-?\d+\.?\d*)\*(?P<sec>[\+\-]?\d+\.?\d*)",a) # 将算式分组,成为两个数字,实质也是约分,取负号。 17 c=float(b.group("fir"))*float(b.group("sec")) # 调用这两个数字进行运算。 18 elif "+" or "-" in a: 19 b=re.search("(?P<fir>\-?\d+\.?\d*)(?P<sign>[\+\-]+)(?P<sec>\d+\.?\d*)",a)#将算式分组,成为两个数字,前面一个必须带符号。 20 if b.group("sign") =="+-" or b.group("sign") == "-" or b.group("sign") == "-+": #评判符号,减号有三种情况。 21 c=float(b.group("fir"))-float(b.group("sec")) # 调用这两个数字进行运算。 22 else:c=float(b.group("fir"))+float(b.group("sec")) 23 c=round(c,100) #将c保留100位小数。 24 if float(b.group("fir")) < 0 and float(b.group("sec")) < 0: #这一步非常重要,如果前面的数字只有一个减号的话,会少个加号, 25 c="+%s" % (str(c)) #但是上面匹配加减法的时候,脂批那个是从最左边的位置开始的,所以不必担心。 26 if len(re.findall("[\+\-]?\d+\.?\d*",a))==2: #如果括号内只剩余两个数字那么就不用再计算了,就将该部分替换为计算结果。 27 s=s.replace(a, str(c),1) #将括号替换计算结果。返回给s。 28 else:#如果括号内大于两个数字,就将算式替换为计算结果,因为search找到第一个匹配就返回,所以安全起见双重归一,replace也是只替换第一部分。 29 s=s.replace(b.group(),str(c),1) #将计算式替换为计算结果。返回给s,加1,双重归一,避免乱替换,有减号就麻烦了。 30 # print(s) 31 # 思路: 32 # 1、从最内层括号入手,按照\-->*-->+的方法来进行计算,始终是两个数字在进行计算,直至将里面的算式全部计算完毕。 33 # 2、替换时分为替换括号整体和算式,注意符号的转变,四则运算规则非常重要。 34 # 3、弥补缺陷,就是 * \ 消符号的弊病,此版本输出地结果都带正负号,可以取结果引用再次作为参数。 35 # 4、正则表达式利用search的特性,找到一个就返回值,可以轮番操这个括号内的内容,group的多元化应用。 36 # 5、其实没有用到多少正则表达式的东西,呵呵,还好我又复习了一遍,不然转眼全忘了。
时间: 2024-10-06 16:38:42