Python编写简单计算器(正则表达式应用)

原文链接: http://www.cnblogs.com/David0207AlwaysHappy/p/10825671.html

需求——开发一个简单的Python计算器

1.实现加减乘除以及括号优先级解析
2.用户输入3+5*((80-40+(-40/8)*(9-2*9/3-5/3*98/4*2998+10*568/14))-(-4*6)/(27-3*8))等类似公式后,必须自己解析出里面的各种符号(不得调用eval等偷懒),运算后得出结果,结果要正确。

总程序

 1 import re
 2 #一、对公式进行简单处理(去掉空格及公式化简)
 3 def format_string(string):
 4     string = string.replace(' ','')
 5     string = string.replace('++','+')
 6     string = string.replace('+-','-')
 7     string = string.replace('-+','-')
 8     string = string.replace('--','+')
 9     string = string.replace('*+','*')
10     string = string.replace('/+','/')
11     return string
12 #二、对于不符合要求的公式进行异常处理,给出错误提示信息
13 def check_expression(string):
14     check_result = True
15     if not string.count("(") == string.count(")"):
16         print('括号不对称')
17         check_result = False
18     if re.findall('[a-z]',string.lower()):
19         print('表达式有错,包含非法字符')
20         check_result = False
21     return check_result
22 #三、进行乘除运算,并将计算的结果替换掉原公式中的乘除法运算
23 def mul_div(string):
24     #正则表达式匹配(匹配乘除)
25     regular = '\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
26     #一直到公式中没有除法或乘法运算时,退出循环
27     while re.findall(regular,string):#注意:乘除法可以没有顺序
28         expression = re.search(regular,string).group()
29         # 计算乘法,并将计算的结果替换原来的式子
30         if expression.count('*'):
31             x,y=expression.split('*')
32             mul_result=str(float(x)*float(y))
33             string=string.replace(expression,mul_result)
34             string=format_string(string)
35         # 计算除法,并将计算的结果替换原来的式子
36         elif expression.count('/'):
37             x, y = expression.split('/')
38             div_result = str(float(x) / float(y))
39             string = string.replace(expression, div_result)
40             string = format_string(string)
41     return string
42 #四、进行加减法运算
43 def add_sub(string):
44     add_regu = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'
45     sub_regu = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'
46     # 计算加法,注意:加减法也可以没有顺序
47     while re.findall(add_regu,string):
48         add_list=re.findall(add_regu,string)
49         for add_str in add_list:
50             x, y = add_str.split("+")
51             add_result = str(float(x) + float(y))
52             string = string.replace(add_str, add_result)
53             string = format_string(string)
54     while re.findall(sub_regu, string):
55         sub_list = re.findall(sub_regu, string)
56         for sub_str in sub_list:
57             numbers = sub_str.split('-')
58             # 计算开头为(-a-b)这种情况
59             if len(numbers) == 3:
60                 result = 0
61                 for v in numbers:
62                     if v:
63                         result -= float(v)
64             else:
65                 x = numbers[0]
66                 y = numbers[-1]
67                 sub_result = float(x) - float(y)
68             string = string.replace(sub_str,str(sub_result))
69             string = format_string(string)
70     return string
71 #五、主逻辑程序
72 info=True
73 while info:
74     source = input("请输入要计算的公式:")
75     if check_expression(source):
76         strs = format_string(source)
77         while source.count('(') > 0:
78             # 匹配最里层括号的内容
79             strs = re.search('\([^()]*\)', source).group()#在这里^是不包含的意思,[^()]+就是不包含括号的所有字符——返回最里面的括号
80             replace_str = mul_div(strs)
81             replace_str = add_sub(replace_str)
82             # 每次计算的结果去掉括号
83             source = format_string(source.replace(strs, replace_str[1:-1]))
84             # else下边的逻辑是计算不带括号的式子
85         else:
86             replace_str = mul_div(source)
87             replace_str = add_sub(replace_str)
88             source = source.replace(source, replace_str)
89     print(source)
90     signal=input("是否继续?y/n")
91     if signal=='y':
92         info=True
93     elif signal=='n':
94         info=False
95 print("已退出,欢迎下次使用!")

难点

1.匹配最里层括号的正则表达式:'\([^()]*\)'

2.匹配乘除法及加减法的正则表达式:

乘除——'\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'

加——'[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'

减——'[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'

3.主逻辑的设计

自我总结

此项目为借助已有代码所写;

相比基本语法,代码整体的逻辑设计更重要;

函数的思想还没有完全掌握;

代码的流程逻辑还需要提升;

其实代码也是模块化的,一个模块想清楚了,其他的也相似。

继续努力!

2019年5月7日



转载于:https://www.cnblogs.com/David0207AlwaysHappy/p/10825671.html

猜你喜欢

转载自blog.csdn.net/weixin_30832351/article/details/94892887