基于re模块的计算器


最终计算器需求:

  1. 实现加减乘除及拓号优先级解析
  2. 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致。

 

a+b

1 1 # 1.用于计算 a+b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。
2 2 
3 3 import re
4 4 
5 5 def addtion():
6 6     formula = input("请输入一个公式(严格按照a+b)格式:")  # 得到一个公式字符串
7 7     num_list = re.split("\+",formula)  # 这里要注意,加号为元字符,前要加转义字符才行。结果得到一个列表 [a,b]
8 8     return float(num_list[0]) + float(num_list[1])  # num_list[0] = "a" 是个字符。需要转成 float 类型
9 9 print(addtion())

a-b

1 # 2.用于计算 a-b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。
2 
3 import re
4 
5 def addtion():
6     formula = input("请输入一个公式(严格按照a-b)格式:")  # 得到一个公式字符串
7     num_list = re.split("-",formula)  # 这里要注意,减号不是元字符。结果得到一个列表 [a,b]
8     return float(num_list[0]) - float(num_list[1])  # num_list[0] = "a" 是个字符。需要转成 float 类型
9 print(addtion())

 a+b 或 a-b

 1 # 3.用于计算 a-b 或者 a+b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。
 2 
 3 import re
 4 
 5 def addtion():
 6     formula = input("请输入一个公式(严格按照a+b或a-b)格式:")  # 得到一个公式字符串
 7     symbol = re.search("[-+]",formula).group()  # 此处serach得到的是个对象,需要调用group()方法,得到一个字符串。
 8     num_list = re.split("[-+]",formula)  # 不需要使用转义符号
 9     if symbol == "-":
10         return float(num_list[0]) - float(num_list[1])  # num_list[0] = "a" 是个字符。需要转成 float 类型
11         
12     else:
13         return float(num_list[0]) + float(num_list[1])  # num_list[0] = "a" 是个字符。需要转成 float 类型
14 print(addtion())

多位数加减(可带空格和 -  符号)比如 - 3 + 4 - 2

 1 def symbol_result(string):
 2     string = string.replace("++","+")
 3     string = string.replace("+-","-")
 4     string = string.replace("-+","-")
 5     string = string.replace("--","+")
 6     return string
 7 
 8 def addtion_reduce(s):        #处理加减法,变成数组,全加
 9     s = symbol_result(s)
10     li = re.findall(r'([\d\.]+|\+|-)', s)
11     print (li)
12     sum = 0
13 
14     for i in range(len(li)):
15         # 碰到 - 符号,就把 - 变成 + ,后面那个数字取反
16         if li[i] == '-':
17             li[i] = '+'
18             li[i+1] = float(li[i+1]) * (-1)
19     for i in li:
20         if i == '+':
21             i = 0
22         sum = sum + float(i)
23     return str(sum)
24 
25 s = input("请输入公式:")
26 addtion_reduce(s)
多位数加减(带括号、负号)

 完整代码

处理过程:

1.当字符串传入后,先处理空格。用字符串方法 replace 处理。

2.处理括号。循环条件,是否有 “(” 。如果有,表示还有括号。用 r'\([^\(\)]+\)' 找到最里层括号,然后做计算。最终返回一个字符串。用这个字符串替换整个括号。

3.计算部分分两块,乘除和加减。先做乘除,乘除用 r'[\d\.]+[*/]-?[\d\.]+' 找到一个字符串。要用 search 一个个处理,findall 太麻烦。找到字符串之后,以 * / 为 分界线,计算。

4.加减 先处理 ++ +- -- 等问题,替换掉。然后把整个式子连同加减符号传入数组。把 - 变成 + ,后面那个元素取反。然后计算。

 1 import re
 2  
 3 def chengchu(s):          #处理带负号的乘除
 4     rRegex = re.compile(r"""
 5         [\d\.]+  # 表示 3 或者 2.2 这样的数字.
 6         [\*/]     # 乘除必有
 7         -?       # 最关键的,有可能出现 (6*-3) 这种式子
 8         [\d\.]+  # 表示 3 或者 2.2 这样的数字.
 9                  # 连在一起就是 r'-?[\d\.]+[*/]-?[\d\.]+'
10         """,re.VERBOSE) 
11 
12     while (("*" in s) or ("/" in s)):
13         # 如果 "*" 或者 "/" 在字符串 s 中,表示还需要做乘除运算
14 
15         ma = rRegex.search(s).group()  # search 用 group 只找第一个
16         li = re.split(r'[\*/]', ma)  # ma 是一个式子,比如 -5.5*-5 。但是 while 里面 表示式子必定有 * 或者 /。以 * 或 / 为分隔符。
17                                     #float 左右两个 -5.5 和 -5。然后做乘除就可以了。
18         print(li,"li")
19 
20         if ("*") in ma:
21             print(ma,"ma*")
22             result = str(float(li[0]) * float(li[1]))
23         else:
24             print(ma,"ma/")
25             result = str(float(li[0]) / float(li[1]))
26         s = s.replace(ma, result, 1)
27 
28     return s
29 
30 def symbol_result(string):
31     string = string.replace("++","+")
32     string = string.replace("+-","-")
33     string = string.replace("-+","-")
34     string = string.replace("--","+")
35     return string
36 
37 def jiajian(s):        #处理加减法,变成数组,全加
38     s = symbol_result(s)
39     li = re.findall(r'([\d\.]+|\+|-)', s)
40     print (li)
41     sum = 0
42 
43     for i in range(len(li)):
44         # 碰到 - 符号,就把 - 变成 + ,后面那个数字取反
45         if li[i] == '-':
46             li[i] = '+'
47             li[i+1] = float(li[i+1]) * (-1)
48     for i in li:
49         if i == '+':
50             i = 0
51         sum = sum + float(i)
52     return str(sum)
53  
54 def simple(s):  #处理不带括号的
55     return jiajian(chengchu(s))
56  
57 def complex(s):  #处理带括号的
58     while '(' in s: 
59         #如果检测到还有括号
60 
61         # reg = re.compile(r'\([^\(\)]+\)')  # 表示最里层的括号))
62         ma = re.search(r'\([^\(\)]+\)', s).group()  # 找到最里层括号内的字符串
63         result = simple(ma[1:-1])  # 用切片去除括号,计算字符串
64         s = s.replace(ma, result, 1)  # 把原先最里层括号字符串替换成计算结果
65     return simple(s)
66  
67 ss = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'.replace(' ', '')
68 # ss = "2*3*38*(2-3)".replace(" ","")
69 print(complex(ss))
70 print(eval(ss))
完整代码

 

posted @ 2018-05-07 14:29  dongye95  阅读(261)  评论(0编辑  收藏  举报