洗礼灵魂,修炼python(80)--全栈项目实战篇(8…
2018-06-18 00:09:08来源:未知 阅读 ()
用正则表达式开发一个计算器,计算用户给定的一串带有加减乘除的公式。
要求:不能使用eval转换字符串
分析:
要求简单,就是计算混合运算,但是不能使用eval直接转换,主要就是把整个式子中的小括号优先匹配到进行计算再把计算结果替换到式子中,然后再根据小括号计算,直到没有小括号再按照加减乘除优先级计算,最后计算出结果。每次计算前把加减乘除符号格式化一下,比如有+和-同时存在的时候
代码发布区:github
#!usr/bin/env python
#-*- coding:utf-8 -*-
# author:yangva
# datetime:2017/12/23 0023 21:31
import re
def format_string(string): #格式化字符串,把符号格式化
string = string.replace('++','+')
string = string.replace('-+','-')
string = string.replace('--','+')
string = string.replace('*+','*')
string = string.replace('/+','/')
string = string.replace(' ','')
return string
def counter_md(string): #乘除
pattern_str2 = '\d+\.?\d*[*/][+\-]?\d+\.?\d*' #匹配乘除法,带上正负号,[]中的 - 有特殊意义,所以要转义
while re.findall(pattern_str2,string):
expression = re.search(pattern_str2,string).group()
#如果有乘法,分割并分别运算
if expression.count('*'):
x,y = expression.split('*')
mul_result = str(float(x)*float(y))
string = string.replace(expression,mul_result)
string = format_string(string)
#如果有除法,分割并分别运算
if expression.count('/'):
x,y = expression.split('/')
div_result = str(float(x)/float(y))
string = string.replace(expression,div_result)
string = format_string(string)
return string
def counter_as(string): #加减
pattern_add = '[\-]?\d+\.?\d*\+[+\-]?\d+\.?\d*' #匹配加法
pattern_sub = '[\-]?\d+\.?\d*\-[+\-]?\d+\.?\d*' #匹配减法
#处理加法
while re.findall(pattern_add,string):
add_list = re.findall(pattern_add,string) #将结果分割成一个小式子
for add_str in add_list: #迭代每个小式子,分别计算
x,y = add_str.split('+')
add_result = '+'+str(float(x)+float(y))
string = string.replace(add_str,add_result) #得到的结果替换到式子中
#处理减法
while re.findall(pattern_sub,string):
sub_list = re.findall(pattern_sub,string)
for sub_str in sub_list:
numbers = sub_str.split('-')
#如果分割出来的小式子里有如-5-3的式子,会分割出['','5','3']则再分割一次
if len(numbers) == 3:
result = 0 #定义变量,方便后续存储结果
for v in numbers:
if v:
result -= float(v)
else: #正常结果,比如4-5,分割得到的则是['4','5']
x,y = numbers
result = float(x) - float(y)
#替换字符串
string = string.replace(sub_str,str(result))
return string
def check(string): #检查合法性
check_flag = True #标志位
if not string.count('(') == string.count(')'):
print('括号数量不统一')
check_flag = False
if re.findall('[a-zA-Z]+',string):
check_flag = False
print('非法字符')
check_flag = False
return check_flag
if __name__ == '__main__':
#info = '20-4+9*((44-22+134/3 - (-3+33+34*5/2*5-9/3*55)-45-3)+55+3*234-2-3×57)'
# 检验合法性
info = input('请输入式子:')
if check(info):
print('info:',info)
info = format_string(info)
print(info)
print('eval(info):',eval(info)) #作为与输出结果对比的验证
while info.count('(') > 0: #计算括号内的式子
pattern_str = re.search('\([^()]*\)',info).group()
#按照运算优先级,先计算乘除法的结果
md_result = counter_md(pattern_str)
#再计算加减法的结果
as_result = counter_as(md_result)
#把计算得到的结果作[1:-1]切片,把括号去掉再重新格式化替换原数据替换到式子中
info = format_string(info.replace(pattern_str,as_result[1:-1]))
else: #计算括号外的式子,不用再匹配直接运算
md_result = counter_md(info)
as_result = counter_as(md_result)
info = info.replace(info,as_result)
print('the result is :',info.replace('+',''))
测试结果就不贴出来了,自己测试了
总结:
通过这个小项目,相信你已经对正则表达式很了解了,那么我的目的就达到了
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:python 模块和包的使用方法
下一篇:python入门教程学习笔记#2
- 洗礼灵魂,修炼python(82)--全栈项目实战篇(10)—— 信 2018-06-23
- 洗礼灵魂,修炼python(81)--全栈项目实战篇(9)—— 购物 2018-06-23
- 洗礼灵魂,修炼python(67)--爬虫篇—cookielib之爬取需要 2018-06-23
- 洗礼灵魂,修炼python(91)-- 知识拾遗篇 —— pymysql模块 2018-06-18
- 洗礼灵魂,修炼python(89)-- 知识拾遗篇 —— 进程 2018-06-18
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
