该计算器主要分为四个模块:

weclome_func函数用来进入界面获取表达式,并判断表达式是否正确,然后返回表达式;

add_sub函数用来进行加减运算,如果有多个加减运算,会递归,最后返回对应的值

multi_divide函数用来进行乘除运算,如果有多个乘除运算,会递归,最后返回对应的值

del_bracket函数用来去除小括号及调用multi_divide和add_sub函数,如果存在多个括号,也会实现递归。

代码如下:

#! /usr/bin/env python3

import sys
import re def welcome_func():
flag_exit = True
welcome_str = "超级计算器"
print(welcome_str.center(50, "*"), '\n')
while flag_exit:
exp = input("请输入要计算的表达式[q:退出]: ").strip()
if exp == "q":
flag_exit = False
elif len(exp) == 0:
continue
else:
exp = re.sub("\s*", '', exp) ## 取出空格
return exp def multi_divide(expression):
val = re.search("\d+\.?\d*[*/][+-]?\d+\.?\d*", expression) ##匹配乘除号,如192.168*-1.99
if not val: # 乘除号不存在,返回输入的表达式
return expression
data = re.search("\d+\.?\d*[*/][+-]?\d+\.?\d*", expression).group()
if len(data.split('*')) > 1: # 当可以用乘号分割,证明有乘法运算
part1, part2 = data.split('*') # 用除号分割
value = float(part1) * float(part2)
else:
part1, part2 = data.split('/')
if float(part2) == 0: # 如果分母为0,则退出计算
sys.exit("计算过程中有被除数为0的存在,计算表达式失败!")
value = float(part1) / float(part2) s1, s2 = re.split("\d+\.?\d*[*/][+-]?\d+\.?\d*", expression, 1) # 分割表达式
next_expression = "%s%s%s" % (s1, value, s2)
return multi_divide(next_expression) # 递归表达式 def add_sub(expression):
expression = expression.replace('+-', '-') # 替换表达式里的所有‘+-‘
expression = expression.replace('--', '+') # 替换表达式里的所有‘--‘
expression = expression.replace('-+', '-') # 替换表达式里的所有‘-+‘
expression = expression.replace('++', '+') # 替换表达式里的所有‘++‘ data = re.search('\d+\.?\d*[+-]\d+\.?\d*', expression) # 匹配加减号
if not data: # 如果不存在加减号,则证明表达式已计算完成,返回最终结果
return expression
val = re.search('[+-]?\d+\.?\d*[+-]\d+\.?\d*', expression).group()
if len(val.split('+')) > 1: # 以加号分割成功,有加法计算
part1, part2 = val.split('+')
value = float(part1) + float(part2)
elif val.startswith('-'): # 如果是已‘-‘开头则需要单独计算
part1, part2, part3 = val.split('-')
value = -float(part2) - float(part3) # 计算以负数开头的减法
else:
part1, part2 = val.split('-')
value = float(part1) - float(part2) s1, s2 = re.split('[+-]?\d+\.?\d*[+-]\d+\.?\d*', expression, 1) # 分割表达式
next_expression = "%s%s%s" % (s1, value, s2)
return add_sub(next_expression) # 递归运算表达式 def del_bracket(expression): ## [^()]+ 匹配除了括号以外的任意字符 if not re.search(r"\([^()]+\)", expression): # 判断小括号,如果不存在小括号,直接调用乘除,加减计算
ret1 = multi_divide(expression)
ret2 = add_sub(ret1)
return ret2 # 返回最终计算结果
data = re.search(r"\([^()]+\)", expression).group() # 如果有小括号,匹配出优先级最高的小括号
print("获取表达式", data)
data = data.strip('[\(\)]') # 剔除小括号
ret1 = multi_divide(data)
# print("全部乘除计算完后的表达式:", ret1)
ret2 = add_sub(ret1)
# print("全部加减计算结果:", ret2)
part1, part2 = re.split(r"\([^()]+\)", expression, 1) # 分割表达式
expression = "%s%s%s" % (part1, ret2, part2)
return del_bracket(expression) # 递归去小括号 if __name__ == "__main__":
try:
expression = welcome_func() ## 获取表达式
print(expression)
result = eval(expression) ## 用eval来验证
print(result)
ret = del_bracket(expression) ## 用函数计算得出结果
result = float(result)
ret = float(ret)
print("eval计算结果: ", result)
print("表达式计算结果: ", ret)
except (SyntaxError, ValueError, TypeError):
print("输入表达式不合法,请检查!")

python 利用正则构建一个计算器的更多相关文章

  1. python 利用栈实现复杂计算器

    #第五周的作业--多功能计算器#1.实现加减乘除及括号的优先级的解析,不能使用eval功能,print(eval(equation))#2.解析复杂的计算,与真实的计算器结果一致#用户输入 1 - 2 ...

  2. 利用 vue-cli 构建一个 Vue 项目

    一.项目初始构建 现在如果要构建一个 Vue 的项目,最方便的方式,莫过于使用官方的 vue-cli . 首先,咱们先来全局安装 vue-cli ,打开命令行工具,输入以下命令: $ npm inst ...

  3. 利用Dockerfile构建一个基于CentOS 7镜像

    利用Dockerfile构建一个基于CentOS 7,包括java 8, tomcat 7,php ,mysql+mycat的镜像. Dockerfile内容如下: FROM centosMAINTA ...

  4. 利用ELK构建一个小型的日志收集平台

    利用ELK构建一个小型日志收集平台 伴随着应用以及集群的扩展,查看日志的方式总是不方便,我们希望可以有一个便于我们查询及提醒功能的平台:那么首先需要剖析有几步呢? 格式定义 --> 日志收集 - ...

  5. 利用maven构建一个spring mvc的helloworld实例

    刚开始学习maven和spring mvc,学的云里雾里的 这里提供一个hello world实例,记录自己的学习之路 首先看maven官网的介绍 Apache Maven is a software ...

  6. 利用Dockerfile构建一个基于centos 7,包括java 8, tomcat 7,php ,mysql+mycat的镜像

    Dockerfile内容如下: FROM centos MAINTAINER Victor ivictor@foxmail.com WORKDIR /root RUN rm -f /etc/yum.r ...

  7. 利用Roslyn构建一个简单的C#交互脚本引擎

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 微软的下一代编译器技术Roslyn是一个里程碑的技术,可以给.NET平台带来无限想象空间.比 ...

  8. Python - 利用flask搭建一个共享服务器

    零.概述 我利用flask搭建了一个简易的共享服务器,分享给大家 一.python代码 import os import time from flask import Flask,render_tem ...

  9. python利用socket写一个文件上传

    1.先将一张图片拖入‘文件上传’的目录下,利用socket把这张图片写到叫‘yuan’的文件中 2.代码: #模拟服务端 import subprocess import os import sock ...

随机推荐

  1. 在 Linux 中安装 Lighttpd Web 服务器

    Lighttpd 是一款开源 Web 服务器软件.Lighttpd 安全快速,符合行业标准,适配性强并且针对高配置环境进行了优化.相对于其它的 Web 服务器而言,Lighttpd 占用内存更少:因其 ...

  2. java基础---->java中nio的使用(一)

    JDK 1.4 中引入的新输入输出 (NIO) 库在标准 Java 代码中提供了高速的.面向块的 I/O.今天我们就简单的学习一下nio的知识.我笑,便面如春花,定是能感动人的,任他是谁. nio的简 ...

  3. Eclipse 安装更多版本SDK

    暂时记下,实在没时间测试了... 安卓应用开发之查eclipse版本号和添加ADT.SDK https://jingyan.baidu.com/article/b0b63dbfc5f49b4a4830 ...

  4. 【BZOJ3831】[Poi2014]Little Bird 单调队列

    [BZOJ3831][Poi2014]Little Bird Description In the Byteotian Line Forest there are   trees in a row. ...

  5. jQuery照片墙相册

    效果体验:http://keleyi.com/keleyi/phtml/jqtexiao/30.htm 本特效支持jquery的版本为1.4.3,暂时不支持1.9以上jquery版本. 代码: < ...

  6. asfd

    $$\sum_{i=1}^n a_i=0$$$$f(x)=x^{x^x}$$

  7. PHP疑难杂症

    下面这种写法是否允许? echo '\n' // \n echo "\n" // 输出换行 直接访问对象不存在的属性,会怎样? $o = new stdClass(); echo ...

  8. Centos7.0安装mysql5.6

    环境 CentOS 7.0(64-bit system) mysql-5.6.37 一.mysql依赖libaio,所以要先安装libaio # yum search libaio           ...

  9. NoSQL 常用资源

    Hadoop:http://www.apache.org/dyn/closer.cgi/hadoop/common/ easyhadoop:https://github.com/xianglei/ea ...

  10. git学习(7)标签管理

    git学习(7)标签管理 1. 建立标签 在发布版本时候,我们通常会在版本库中打一个标签,这样就唯一确定了打标签的版本,有点像个里程碑,这里会有一个指向某个commit的指针 打标签很简单,首先切换到 ...