基于re模块的计算器
最终计算器需求:
- 实现加减乘除及拓号优先级解析
- 用户输入 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.用于计算 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
# 2.用于计算 a-b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。 import re def addtion():
formula = input("请输入一个公式(严格按照a-b)格式:") # 得到一个公式字符串
num_list = re.split("-",formula) # 这里要注意,减号不是元字符。结果得到一个列表 [a,b]
return float(num_list[0]) - float(num_list[1]) # num_list[0] = "a" 是个字符。需要转成 float 类型
print(addtion())
a+b 或 a-b
# 3.用于计算 a-b 或者 a+b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。 import re def addtion():
formula = input("请输入一个公式(严格按照a+b或a-b)格式:") # 得到一个公式字符串
symbol = re.search("[-+]",formula).group() # 此处serach得到的是个对象,需要调用group()方法,得到一个字符串。
num_list = re.split("[-+]",formula) # 不需要使用转义符号
if symbol == "-":
return float(num_list[0]) - float(num_list[1]) # num_list[0] = "a" 是个字符。需要转成 float 类型 else:
return float(num_list[0]) + float(num_list[1]) # num_list[0] = "a" 是个字符。需要转成 float 类型
print(addtion())
多位数加减(可带空格和 - 符号)比如 - 3 + 4 - 2
def symbol_result(string):
string = string.replace("++","+")
string = string.replace("+-","-")
string = string.replace("-+","-")
string = string.replace("--","+")
return string def addtion_reduce(s): #处理加减法,变成数组,全加
s = symbol_result(s)
li = re.findall(r'([\d\.]+|\+|-)', s)
print (li)
sum = 0 for i in range(len(li)):
# 碰到 - 符号,就把 - 变成 + ,后面那个数字取反
if li[i] == '-':
li[i] = '+'
li[i+1] = float(li[i+1]) * (-1)
for i in li:
if i == '+':
i = 0
sum = sum + float(i)
return str(sum) s = input("请输入公式:")
addtion_reduce(s)
多位数加减(带括号、负号)
完整代码
处理过程:
1.当字符串传入后,先处理空格。用字符串方法 replace 处理。
2.处理括号。循环条件,是否有 “(” 。如果有,表示还有括号。用 r'\([^\(\)]+\)' 找到最里层括号,然后做计算。最终返回一个字符串。用这个字符串替换整个括号。
3.计算部分分两块,乘除和加减。先做乘除,乘除用 r'[\d\.]+[*/]-?[\d\.]+' 找到一个字符串。要用 search 一个个处理,findall 太麻烦。找到字符串之后,以 * / 为 分界线,计算。
4.加减 先处理 ++ +- -- 等问题,替换掉。然后把整个式子连同加减符号传入数组。把 - 变成 + ,后面那个元素取反。然后计算。
import re def chengchu(s): #处理带负号的乘除
rRegex = re.compile(r"""
[\d\.]+ # 表示 3 或者 2.2 这样的数字.
[\*/] # 乘除必有
-? # 最关键的,有可能出现 (6*-3) 这种式子
[\d\.]+ # 表示 3 或者 2.2 这样的数字.
# 连在一起就是 r'-?[\d\.]+[*/]-?[\d\.]+'
""",re.VERBOSE) while (("*" in s) or ("/" in s)):
# 如果 "*" 或者 "/" 在字符串 s 中,表示还需要做乘除运算 ma = rRegex.search(s).group() # search 用 group 只找第一个
li = re.split(r'[\*/]', ma) # ma 是一个式子,比如 -5.5*-5 。但是 while 里面 表示式子必定有 * 或者 /。以 * 或 / 为分隔符。
#float 左右两个 -5.5 和 -5。然后做乘除就可以了。
print(li,"li") if ("*") in ma:
print(ma,"ma*")
result = str(float(li[0]) * float(li[1]))
else:
print(ma,"ma/")
result = str(float(li[0]) / float(li[1]))
s = s.replace(ma, result, 1) return s def symbol_result(string):
string = string.replace("++","+")
string = string.replace("+-","-")
string = string.replace("-+","-")
string = string.replace("--","+")
return string def jiajian(s): #处理加减法,变成数组,全加
s = symbol_result(s)
li = re.findall(r'([\d\.]+|\+|-)', s)
print (li)
sum = 0 for i in range(len(li)):
# 碰到 - 符号,就把 - 变成 + ,后面那个数字取反
if li[i] == '-':
li[i] = '+'
li[i+1] = float(li[i+1]) * (-1)
for i in li:
if i == '+':
i = 0
sum = sum + float(i)
return str(sum) def simple(s): #处理不带括号的
return jiajian(chengchu(s)) def complex(s): #处理带括号的
while '(' in s:
#如果检测到还有括号 # reg = re.compile(r'\([^\(\)]+\)') # 表示最里层的括号))
ma = re.search(r'\([^\(\)]+\)', s).group() # 找到最里层括号内的字符串
result = simple(ma[1:-1]) # 用切片去除括号,计算字符串
s = s.replace(ma, result, 1) # 把原先最里层括号字符串替换成计算结果
return simple(s) 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(' ', '')
# ss = "2*3*38*(2-3)".replace(" ","")
print(complex(ss))
print(eval(ss))
完整代码
基于re模块的计算器的更多相关文章
- 满满干货!手把手教你实现基于eTS的分布式计算器
最近收到很多小伙伴反馈,想基于扩展的TS语言(eTS)进行HarmonyOS应用开发,但是不知道代码该从何处写起,从0到1的过程让新手们抓狂. 本期我们将带来"分布式计算器"的开发 ...
- 8. 博客系统| 富文本编辑框和基于bs4模块防御xss攻击
views.py @login_required def cn_backend(request): article_list = models.Article.objects.filter(user= ...
- 基于nginx-rtmp-module模块实现的HTTP-FLV直播模块(nginx-http-flv-module)
本文后续的内容将在这里更新:<基于nginx-rtmp-module模块实现的HTTP-FLV直播模块(nginx-http-flv-module)续>.注意:下文的配置很多已经不能用了, ...
- 基于ngx_lua模块的waf开发实践
0x00 常见WAF简单分析 WAF主要分为硬件WAF和软件防火墙,硬件WAF如绿盟的NSFOCUS Web Application Firewall,软件防火墙比较有名的是ModSecurity,再 ...
- 基于pymysql模块的增删改查
上课笔记 重点:(熟练)多表查询创建存储过程原生sql索引原理 pymysql 封装好的客户端cursor 底层就是一个send操作commit 告诉mysql真的要完成修改操作(不然修改不会生效)e ...
- 基于requests模块的cookie,session和线程池爬取
目录 基于requests模块的cookie,session和线程池爬取 基于requests模块的cookie操作 基于requests模块的代理操作 基于multiprocessing.dummy ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(Wi-Fi模块AT指令TCP透传方式),MQTT通信控制升级
实现功能概要 前面的版本都是,定时访问云端的程序版本,如果版本不一致,然后下载最新的升级文件,实现升级. 这一节,在用户程序里面加入MQTT通信,执行用户程序的时候,通过接收MQTT的升级命令实现升级 ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于GPRS模块(Air202,SIM800)AT指令TCP透传方式,MQTT通信控制升级
实现功能概要 这节和上一节的功能一样(只不过上节是利用Wi-Fi模块,这节是利用GPRS模块) 用户程序里面加入MQTT通信,执行用户程序的时候, 通过接收MQTT的升级命令实现升级. 凡是可以实现M ...
- ESA2GJK1DH1K升级篇: 移植远程更新程序到STM32F103RET6型号的单片机,基于(GPRS模块AT指令TCP透传方式)
前言 上节实现远程更新是更新的STM32F103C8T6的单片机 GPRS网络(Air202/SIM800)升级STM32: 测试STM32远程乒乓升级,基于(GPRS模块AT指令TCP透传方式),定 ...
随机推荐
- oracle存储过程中%type的含义
转: oracle存储过程中%type的含义 2018-11-07 11:43:56 lizhi_ma 阅读数 1361更多 分类专栏: 数据库 版权声明:本文为博主原创文章,遵循CC 4.0 B ...
- 全面系统Python3入门+进阶-1-5 一个经典误区
结束
- 【Git】 Git安装及配置
Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理.而国外的GitHub和国内的Coding都是项目的托管平台. 本例使用环境:Linux环境(CentOS 7.4 ...
- MySQL数据库查找多个字段值全部相同的记录
数据库中用户表,数据从第三方系统导入,由于一些垃圾数据,存在用户名和密码都相同的账户,造成接口上一些问题,SQL语句如下: and Account2>;
- 使用origin画SCI论文图
使用origin画SCI论文图 觉得有用的话,欢迎一起讨论相互学习~Follow Me start 使用的是OriginPro这款软件,这款软件的特点是 一个字 好 . 新建工作簿并导入数据 可以使用 ...
- CNN中计算量FLOPs的计算
1.FLOPs的概念:全称是floating point operations per second,意指每秒浮点运算次数,即用来衡量硬件的计算性能:在CNN中用来指浮点运算次数: 2.计算过程: 如 ...
- replicationController 使用
[root@lab2 nginx-harbor]# cat http-test.yaml apiVersion: v1 kind: ReplicationController metadata: na ...
- 《MySQL必知必会》学习笔记——附录B 样例表
附录B 样例表 本附录简要描述本书中所用的表及它们的用途. 编写SQL语句需要对基础数据库的设计有良好的理解.不知道什么信息存储在什么表中,表之间如何关联以及行内数据如何分解,是不可能编写出高效的SQ ...
- 钩子(hook)
钩子(hook)编程 钩子(hook)编程 一.钩子介绍 1.1钩子的实现机制 钩子英文名叫Hook,是一种截获windows系统中某应用程序或者所有进程的消息的一种技术.下图是windows ...
- Ubuntu 18.04 使用标准Ubuntu 仓库进行自动化安装NVIDIA驱动
首先,检测你的NVIDIA显卡型号和推荐的驱动程序的模型.在命令行中输入如下命令: $ ubuntu-drivers devices == /sys/devices/pci0000:/::::00.0 ...