爱根,听闻根体欠安,吾茶饭不思夜不能寐,欲语泪先流!!!计算器!

 1 while True:
 2     s="0+%s"%input("please input you number str:").replace(" ","")
 3     print("------------------------%s"%eval(s))
 4     import re
 5     while True:
 6         a=re.search('([^()]+)',s)  #得到带括号的一个算式。
 7         if a !=None:    a=a.group()  #如果有返回值,说明有括号,那么再将a的所有值取出来group做成字符串。
 8         if a ==None:    a=s          #如果没有返回值,说明没有括号了,必须将返回的字符串进行计算。
 9         if len(re.findall("[+-]?d+.?d*",a))==1 and len(re.findall('([^()]+)',s))==0:#如果字符串中只有一个数字,而且没有(),
10             print(s.replace("+",""))        #那么返回这个数字,说明已经得到了最终的结果。2776672.6951997154
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("sec") == "":                          #且去掉--,没用。
21                 c = float(b.group("fir").replace("--","+"))   #如果sec是空的话,说明最原始输入的算式里面就一个数字,则不用再进行计算。
22             elif b.group("sign") in ["+-","-","-+","+-+","++-"]: #评判符号,减号有五种情况,后两种是为了进行最前面0+的运算。
23                 c=float(b.group("fir"))-float(b.group("sec"))  #调用这两个数字进行运算。
24             else: c=float(b.group("fir"))+float(b.group("sec")) #其他的都是加法。
25         if b.group("sec") != "" and float(b.group("fir"))<0 and float(b.group("sec"))<0: #这一步非常重要,如果前面的数字只有一个
26             c="+%s" % (str(c))  #减号的话,会少个加号,但是上面匹配加减法的时候,一直是从左向右的,所以不必担心,第一个条件加上,避免报错。
27         if len(re.findall("[+-]?d+.?d*",a))==2 or b.group("sec")=="": #如果括号内只剩余两个数字,或者输入的时候括号内就剩余一个
28             s=s.replace(a, str(c),1) #数字那么就不用再计算了。将括号和括号内的算式替换计算结果。返回给s。括号为一体
29             s=s.replace("(--","(",1) # ,其实不用加1。然后开始是两个“--”的时候,需要去掉,没用,影响计算。
30         else:#如果括号内大于两个数字,就将算式替换为计算结果,因为search找到第一个匹配就返回,所以安全起见双重归一,replace也是只替换第一部分。
31             s=s.replace(b.group(),str(c),1)   #将计算式替换为计算结果。返回给s,加1,双重归一,避免乱替换,有减号就麻烦了。
32 # 思路:
33 # 1、从最内层括号入手,按照-->*-->+的方法来进行计算,始终是两个数字在进行计算,直至将里面的算式全部计算完毕。
34 # 2、替换时分为替换括号整体和算式,注意符号的转变,四则运算规则非常重要。
35 # 3、弥补缺陷,就是 *  消符号的弊病,此版本输出地结果都带正负号,可以取结果引用再次作为参数。
36 # 4、正则表达式利用search的特性,找到一个就返回值,可以轮番操这个括号内的内容,group的多元化应用。
37 # 5、其实没有用到多少正则表达式的东西,呵呵,还好我又复习了一遍,不然转眼全忘了。
38 #test=1 - 2 * ((60 - 30 + (-40 / 5) * (9 - 2 * 5 / 3 + 7 / 3 * 99 / 4 * 2998 + 10 * 568 / 14)) - (-4 * 3) / (16 - 3 * 2))
39 #test1=--1-(+40)/(-5)-1/(+1)-(-3*3/-3+6/(+6))/(-1)*(-5)-(5)/(9)+(-3/7)
40 #test2=-1-(+40)/(-5)-1/(+1)-(-3*3/-3+6/(+6)/(-1)*(-5)-(5))/(9)+(-3*7-(-4/2)/7)
41 #test3=-(-5)/(+3)
42 #test4=-(+5)/(-4)
43 #test5=-(-1)
44 #test6=(-(-5)/(+5))
45 #test7=(--5)
原文地址:https://www.cnblogs.com/chedanlangren/p/6784351.html