基于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透传方式),定 ...
随机推荐
- openresty开发系列30--openresty中使用http模块
OpenResty默认没有提供Http客户端,需要使用第三方提供的插件 我们可以从github上搜索相应的客户端,比如https://github.com/pintsized/lua-resty-ht ...
- Python3基础 print 格式化输出 %f %d 保留浮点数的位数 整数的位数不够零来凑
Python : 3.7.3 OS : Ubuntu 18.04.2 LTS IDE : pycharm-community-2019.1.3 ...
- RHEL7 的注册
RHEL7 的注册 2016年09月12日 20:37:19 wojiushiwoba 阅读数 13002更多 分类专栏: 嵌入式linux 版权声明:本文为博主原创文章,遵循CC 4.0 BY- ...
- 转 linux下ClamAV使用
linux下ClamAV使用 第一步:Clamav下载http://www.clamav.net/downloads#yuminstall wget –y第二步:创建clamav用户和组groupad ...
- 《Learning a Discriminative Feature Network for Semantic Segmentation》解读
旷世18年的CVPR,论文链接:https://arxiv.org/abs/1804.09337 Motivation:针对分割中的“类内不一致”和“类间一致性”的两大问题,设计了结合Smooth n ...
- 【转】百万年薪挖了p8,难道是水货?
大厦新搬进来一家创业公司,老板红光满面地提着果篮上楼拜访,说是刚拿到了投资人的钱,正准备扩充团队大干一场.那个时候的他踌躇满志,顾盼生辉.当时我想,能在这个大环境下拿到投资的公司,做的产品应该是有前景 ...
- 【opencv】opencv函数isContinuous
isContinuous 参考 1. opencv_isContinuous; 完
- cordon、drain、delete node区别
cordon.drain.delete node区别 主要目的:导致node处于不可调度状态,新创建的pod容器不会调度在node上. cordon将node置为SchedulingDisabled不 ...
- 安装Windows和Ubuntu双系统
发现关注消息 安装Windows和Ubuntu双系统 安装Windows和Ubuntu双系统 0.552016.12.10 15:54:41字数 2101阅读 6644 这几天开始动手做毕设啦 ...
- android基础---->传感器的使用
现在每部Android 手机里面都会内置有许多的传感器,它们能够监测到各种发生在手机上的物理事件,而我们只要灵活运用这些事件就可以编写出很多好玩的应用程序.今天我们开始简单的传感器使用的学习. 目录导 ...