最终计算器需求:

  1. 实现加减乘除及拓号优先级解析
  2. 用户输入 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模块的计算器的更多相关文章

  1. 满满干货!手把手教你实现基于eTS的分布式计算器

    最近收到很多小伙伴反馈,想基于扩展的TS语言(eTS)进行HarmonyOS应用开发,但是不知道代码该从何处写起,从0到1的过程让新手们抓狂. 本期我们将带来"分布式计算器"的开发 ...

  2. 8. 博客系统| 富文本编辑框和基于bs4模块防御xss攻击

    views.py @login_required def cn_backend(request): article_list = models.Article.objects.filter(user= ...

  3. 基于nginx-rtmp-module模块实现的HTTP-FLV直播模块(nginx-http-flv-module)

    本文后续的内容将在这里更新:<基于nginx-rtmp-module模块实现的HTTP-FLV直播模块(nginx-http-flv-module)续>.注意:下文的配置很多已经不能用了, ...

  4. 基于ngx_lua模块的waf开发实践

    0x00 常见WAF简单分析 WAF主要分为硬件WAF和软件防火墙,硬件WAF如绿盟的NSFOCUS Web Application Firewall,软件防火墙比较有名的是ModSecurity,再 ...

  5. 基于pymysql模块的增删改查

    上课笔记 重点:(熟练)多表查询创建存储过程原生sql索引原理 pymysql 封装好的客户端cursor 底层就是一个send操作commit 告诉mysql真的要完成修改操作(不然修改不会生效)e ...

  6. 基于requests模块的cookie,session和线程池爬取

    目录 基于requests模块的cookie,session和线程池爬取 基于requests模块的cookie操作 基于requests模块的代理操作 基于multiprocessing.dummy ...

  7. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(Wi-Fi模块AT指令TCP透传方式),MQTT通信控制升级

    实现功能概要 前面的版本都是,定时访问云端的程序版本,如果版本不一致,然后下载最新的升级文件,实现升级. 这一节,在用户程序里面加入MQTT通信,执行用户程序的时候,通过接收MQTT的升级命令实现升级 ...

  8. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于GPRS模块(Air202,SIM800)AT指令TCP透传方式,MQTT通信控制升级

    实现功能概要 这节和上一节的功能一样(只不过上节是利用Wi-Fi模块,这节是利用GPRS模块) 用户程序里面加入MQTT通信,执行用户程序的时候, 通过接收MQTT的升级命令实现升级. 凡是可以实现M ...

  9. ESA2GJK1DH1K升级篇: 移植远程更新程序到STM32F103RET6型号的单片机,基于(GPRS模块AT指令TCP透传方式)

    前言 上节实现远程更新是更新的STM32F103C8T6的单片机 GPRS网络(Air202/SIM800)升级STM32: 测试STM32远程乒乓升级,基于(GPRS模块AT指令TCP透传方式),定 ...

随机推荐

  1. typescript类 继承 修饰符

    //1.ts中类的定义 /* es5: function Person(name){ this.name=name; this.run=function(){ console.log(this.nam ...

  2. oracle根据sqlID查找相对应的sql语句

    转: 根据sqlID查找相对应的sql语句 2019-07-25 14:47:20 猛豪 阅读数 567更多 分类专栏: 数据库   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议 ...

  3. gitlab 配置到jenkins

    直接把公匙配到了gitlab,然后填入jenkins https://blog.csdn.net/zhufengyan521521/article/details/81219193  配置全局凭据 h ...

  4. SqlServer触发器常用语法AFTER、INSTEAD OF及其详解

    先创建一个简单的触发器 CREATE TRIGGER trigger_name ON table_name [WITH ENCRYPTION] FOR | AFTER | INSTEAD OF [DE ...

  5. LODOP打印table超宽用省略号带'-'的内容换行问题

    前面的博文有div超宽隐藏(LODOP打印超过后隐藏内容样式),还有有table设置超宽隐藏(),此外,还有超宽后用省略号表示的css样式,此文是针对这个样式的.该样式正常情况下没问题,但是遇到-短线 ...

  6. CSS网站框架及样式命名规范

    CSS网站框架 复位:reset.css 基础:base.css 或 basic.css (字体大小.颜色.背景.行高.列表样式.按钮样式.表格样式等等) 布局:layout.css (非结构的布局) ...

  7. Navicat Premium教程

    介绍 Navicat premium是一款数据库管理工具,是一个可多重连线资料库的管理工具,它可以让你以单一程式同时连线到 MySQL.SQLite.Oracle 及 PostgreSQL 资料库,让 ...

  8. mysql 事物控制语言

    事务控制语言(DTL)    什么是事务        通常,在此之前,我们说,一条语句使用一个分号(;)来结束,并得到执行.        那么我们说,这个“一次性执行”的过程,可以称为“一个事务” ...

  9. TypeScript之路----探索接口(interface)的奥秘

    TypeScript定义接口 要想掌握typescript的知识,接口是其必经之路.很多东西都需要接触到接口,接口除了对类的一部分行为进行抽象以外,也常用于对对象的形状进行描述.接下来我们就一起来学习 ...

  10. linux CentOS7 安装字体库-转

    前言 报表中发现有中文乱码和中文字体不整齐(重叠)的情况,首先考虑的就是操作系统是否有中文字体,在CentOS 7中发现输入命令查看字体列表是提示命令无效: 如上图可以看出,不仅没有中文字体,连字体库 ...