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.每次运算完一步要格式化表达式以防出现+-等格式匹配不了正则

文章图片
计算器思路流程.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)
运行一下吧:

文章图片
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
推荐阅读
- FPGA自学|FPGA的I2C的原理及应用(含有源码)
- 企业想要开发APP应用前期需要做哪些准备工作?
- WebXR 技术调研 - 在浏览器中构建扩展现实(XR)应用
- 阿里云云原生加速器企业硬之城携手阿里云|阿里云云原生加速器企业硬之城携手阿里云 Serverless 应用引擎(SAE)打造低代码平台
- Python利用watchdog模块监控文件变化
- java|Java教程(如何使用Jib插件容器化SpringBoot应用())
- python|Python是如何表示时间的(——2个模块、3种方式,1文完成~)
- CMT120 模块
- vue.js|electron + vue 打包桌面应用
- vue|Vue+Electron开发跨平台桌面应用(实战)