最终计算器需求:

  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. NonSerialized 属性忽略序列化报错'NonSerialized' is not valid on this declaration type

    [XmlIgnore] [NonSerialized] public List<string> paramFiles { get; set; } //I get the following ...

  2. nginx: [warn] conflicting server name "aaa.bbbb.com" on 0.0.0.0:80, ignored

    date: 2019-08-12  16:52:44 author: headsen chen notice :个人原创 故障现象: openresty -t nginx: [warn] confli ...

  3. 使用localStorage写一个简单的备忘录

    使用html+js实现一个简单的备忘录,主要体会一下localStorage的用法. 先看看效果图: 在输入框中输入文字,点击保存按钮,文本内容会在下放展示出来, 然后刷新下浏览器,会发现文本内容不会 ...

  4. 为什么static成员必须在类外初始化,而不能在类的头文件中初始化

    为什么static成员必须在类外初始化 为什么静态成员不能在类内初始化 在C++中,类的静态成员(static member)必须在类内声明,在类外初始化,像下面这样.   class A { pri ...

  5. hadoop记录-flink测试

    1.启动集群 bin/start-cluster.sh 2.jps查看进程 3.打开网页端(192.168.66.128:8081) 4.造数据:nc -lk 9000 5.执行./bin/flink ...

  6. 获取Django model中字段名,字段的verbose_name,字段类型

    如下app:ywreport下存在model:Game: class Game(models.Model): name = models.CharField(u'游戏名称',max_length=30 ...

  7. log4net示例2-日志输入存入Access(转)

    需求:基于log4net组建,创建Console程序将日志输出到Access数据库. 具体实施: (1)创建控制台程序. (2)控制台程序中,添加一个纯文本文件,文件命名为“log-Access.se ...

  8. 一些Python中的二维数组的操作方法

    一些Python中的二维数组的操作方法 这篇文章主要介绍了一些Python中的二维数组的操作方法,是Python学习当中的基础知识,需要的朋友可以参考下 需要在程序中使用二维数组,网上找到一种这样的用 ...

  9. AD 常用策略

    配置WSUS 配置NTPS 配置用户配置文件漫游 配置漫游区磁盘配额 配置修改本地管理员用户名 配置修改本地管理员密码 配置网络验证(提示是否联网错误) 配置允许开设永久共享 配置允许开设共享打印机 ...

  10. Swift4.0复习泛型

    1.泛型的基本使用: /// 定义了一个泛型结构体MyStruct, /// 其泛型形参为T struct MyStruct<T> {   /// 用泛型T定义存储式成员属性t var t ...