Python3.6:re模块应用-简单的计算器

【Python3.6:re模块应用-简单的计算器】既然学到了re模块,就做个简单计算器应用一下吧!
随便打了一段表达式:
2*( 60--30)+(40/5)*(2*+6/3++6/3*100 /-4*2 +1 0* 5/5)+33
本来想写一下自己的思路,但是试了一下发现一写就有很多细枝末节,写出来很乱,就将大致思路画了个流程图,然后详解写在代码注释里,不过有两个注意点:

1.每次函数体进去的数据类型为str出来也要为str
2.每次运算完一步要格式化表达式以防出现+-等格式匹配不了正则
先看流程:

Python3.6:re模块应用-简单的计算器
文章图片
计算器思路流程.png
然后是自己的代码:
#__Author:zj #__Date:2018/1/1import redef check(s): flag = True if re.findall('[a-zA-Z]', s): print('表达式不规范!') flag = False return flagdef format_string(string): string = string.replace('--', '+') string = string.replace('-+', '_') string = string.replace('++', '+') string = string.replace('+-', '-') string = string.replace('*+', '*') string = string.replace('/+', '/') string = string.replace('+*', '*') string = string.replace('+/', '/') return stringdef mul_div(expression): mul_div_regular = '\d+\.?\d*[*/]\d+\.?\d*' ret = re.search(mul_div_regular, expression) if not ret: return expression else: ret1 = ret.group() if len(ret1.split('/')) > 1: x, y = ret1.split('/') result = float(x) / float(y) if len(ret1.split('*')) > 1: x, y = ret1.split('*') result = float(x) * float(y) else: pass result1 = str(result) re_expr = re.sub(mul_div_regular, result1, expression, count=1) fina_expr = mul_div(format_string(re_expr)) return fina_exprdef add_sub(expression): add_sub_regular = '\-?\d+\.?\d*[\+\-]\d+\.?\d*' ret = re.search(add_sub_regular, expression) if not ret: return expression else: ret1 = ret.group() if len(ret1.split('+')) > 1: x, y = ret1.split('+') result = float(x)+float(y) else: x, y = ret1.split('-') result = float(x) - float(y) result1 = str(result) re_expr = re.sub(add_sub_regular, result1, expression, count=1) fina_expr = add_sub(format_string(re_expr)) return fina_exprif __name__ == '__main__': source = input('请输入表达式(退出q):') if check(source): source = source.replace(' ', '') source = format_string(source) print('表达式:', source)while source.count('(') > 0: strs = re.search('\([^()]+\)', source).group() replace_str = mul_div(strs) replace_str = add_sub(replace_str) source = format_string(source.replace(strs, replace_str[1:-1])) else: replace_str = mul_div(source)replace_str = add_sub(replace_str) print(replace_str)

运行一下吧:

Python3.6:re模块应用-简单的计算器
文章图片

get it!
下面放一下解释:
#__Author:zj #__Date:2018/1/1import re#这里是检查是否有字母函数 def check(s): #定义一个变量True,判断是否有字母,有字母退出,没字母返回True flag = True if re.findall('[a-zA-Z]', s): print('表达式不规范!') flag = False return flag#格式化字符串函数将一些'--''+-''*+''-+'等不规则的转换为规则的下面很多步骤都要用 def format_string(string): string = string.replace('--', '+') string = string.replace('-+', '_') string = string.replace('++', '+') string = string.replace('+-', '-') string = string.replace('*+', '*') string = string.replace('/+', '/') string = string.replace('+*', '*') string = string.replace('+/', '/') #返回格式完的表达式 return string#这里是乘除函数 def mul_div(expression): #定义正则表达式可以匹配到类似'x*y' / 'x/y' mul_div_regular = '\d+\.?\d*[*/]\d+\.?\d*' #得到匹配到的第一个符合的表达式字符段 ret = re.search(mul_div_regular, expression) #这里判断是否找到乘除表达式了,如果匹配为空,直接返回这个表达式进行加减运算就可以了 if not ret: return expression #如果不为空就说明匹配到了,就开始运算 else: #获得这个字符串 ret1 = ret.group() #判断是否有/ if len(ret1.split('/')) > 1: x, y = ret1.split('/') result = float(x) / float(y) #判断是否有* if len(ret1.split('*')) > 1: x, y = ret1.split('*') result = float(x) * float(y) #没有的话直接pass就行了,就会剩加减到下个函数运行 else: pass #得到的浮点型要强制转换字符串 result1 = str(result) #这里是用字符串结果替换刚找到的这个表达式块例如(x*y) re_expr = re.sub(mul_div_regular, result1, expression, count=1) #上面是运算了一小块,这里是不断调用乘除运算并且每次调用都会格式化表达式,直到表达式没有乘除符号了就返回这个括号内表达式的结果了 fina_expr = mul_div(format_string(re_expr)) return fina_expr#这是加减函数 def add_sub(expression): #定义正则表达式 add_sub_regular = '\-?\d+\.?\d*[\+\-]\d+\.?\d*' #下面跟上面没有大区别,上面能看懂,这里也能看懂 ret = re.search(add_sub_regular, expression) if not ret: return expression else: ret1 = ret.group() if len(ret1.split('+')) > 1: x, y = ret1.split('+') result = float(x)+float(y) else: x, y = ret1.split('-') result = float(x) - float(y) result1 = str(result) re_expr = re.sub(add_sub_regular, result1, expression, count=1) #不断调用加减函数并格式化字符串 fina_expr = add_sub(format_string(re_expr)) return fina_exprif __name__ == '__main__': source = input('请输入表达式(退出q):') #检查是否有字母 if check(source): #去空格去一次就够了 source = source.replace(' ', '') #格式化 具体看上面format_string()函数 source = format_string(source) print('表达式:', source)#进入while循环,只要有括号,就一直在这个循环里运行 while source.count('(') > 0: #寻找第一个最内层括号以字符串的格式获取 strs = re.search('\([^()]+\)', source).group() #运行第一个括号内的乘除得到返回值 replace_str = mul_div(strs) #运行此括号内的加减并得到返回值 replace_str = add_sub(replace_str) #得到字符串是结果和括号,去掉括号并在整体表达式中用结果替换原先的内容 到这里相当于运算了一个括号里的表达式并用结果替代了原先的位置 source = format_string(source.replace(strs, replace_str[1:-1])) #然后上去继续判断是否还有括号,有括号就继续,直到剩下没有括号的表达式运行else else: #没有括号的表达式直接先乘除运算后加减运算 replace_str = mul_div(source) replace_str = add_sub(replace_str) #输出结果 print(replace_str)

表达能力有限,写的不好请见谅
还有就是这个代码依然有很多bug,希望大家能多提意见和改进方法
转载请标明出处
python自学技术互助扣扣群:670402334

    推荐阅读