在 Alex 的博客上看到的对正则这一章节作业是编写一个计算器,要求能计算出下面的算式。

1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )

第一次编写计算器,为了理清逻辑,先编写一个 比较初级的版本,暂时只支持加减乘除。
分析上面的计算式,虽然只有加减乘除,但是还是比较复杂的运算,上面的计算式基本上是涵盖了所有加减乘除能遇到的所有情况。
我们先设一个计算器程序能达到的效果,运行程序时,程序要求用户输入一个计算式,然后程序计算结束后,返回一个值,也就是计算式最后的值。

程序比较关键的几点:
1.初步判断和处理用户提供的字符串,判断是否是正确的算式,其中包括,算式中是否出现了英文字母,左括号和右括号是否相等,去掉字符串中的空格,更复杂的判断先暂时不做。

2.计算顺序,由于计算是有优先级的,如果人工算,第一步就是去找最里层的括号,将最里层的括号的值在代出来计算运算。那么程序第一步就是判断计算式中是否有括号,如果有括号,就找到最里层的扩号,计算完后,就用得到的值来替换最里层的括号,得到一个新的字符串,在返回继续判断是否有括号,再计算,如此循环得到最后的值。

**3.那么怎么来让程序来识别哪一个括号才是最里层的括号呢?由于正则默认的是贪婪匹配,找到最外层扩号很容易,找到最里层的反而不是太容易。换个思路,只要不是最里层的括号,那么这个括号里面一定还有括号,所以最里层的括号有一个特点,就是里面不再会有其他括号了。故正则可以这样写 '\(([^()]+)\)' 。(这是这个程序实现的最关键的一点)**

4 . 程序不完善之处,这个程序只支持加减乘除四则运算,功能还不够完善;由于python 自身的原因,在计算浮点数上,有时会出现不准确的情况,这个还需要在完善一下;为了方便处理,我是将所有的数字都转化为浮点数处理,故一些整数间的运算得到的结果也会是一个浮点数,还需要继续完善。
附上代码:

  1. ```
  2. import re
  3.  
  4. x = input('请输入你要计算的计算式:') # 用户输入
  5. # 判断用户输入的是否有字母,括号个数是否正确,同时处理字符串中的空格
  6.  
  7. if re.findall('[a-zA-Z]',x):
  8. print('输入错误,算式中出现字母!')
  9. exit()
  10. if '(' in x or ')' in x:
  11. if x.count('(') != x.count(')'):
  12. print('输入错误,括号个数不正确!')
  13. exit()
  14. if ' ' in x:
  15. x = x.replace(' ','')
  16.  
  17. # 定义一个处理乘法和除法的函数,在只有加减乘除的运算中,除法若是最优先运算的话,不会出错。
  18. # 经过这个函数处理后,计算式中的 乘除法就处理完了,只剩下加减法了
  19. def multiplication_division(calculate):
  20. # 在计算完括号里面的计算式时,如果得到一个负数,那么替换后会出现 '*-' '/-' '+-' '--' 这么几种情况,故函数先判断处理这种情况。
  21. while '*-' in calculate:
  22. if re.search('-[0-9.]+\*-',calculate):
  23. replace1 = re.search('-[0-9.]+\*-',calculate).group()
  24. replace = replace1.replace('*-','*')
  25. replace = replace.replace('-','+')
  26. calculate = calculate.replace(replace1,replace)
  27. elif re.search('\+[0-9.]+\*-',calculate):
  28. replace1 = re.search('\+[0-9.]+\*-', calculate).group()
  29. replace = replace1.replace('*-', '*')
  30. replace = replace.replace('+', '-')
  31. calculate = calculate.replace(replace1, replace)
  32. while '/-' in calculate:
  33. if re.search('-[0-9.]+/-',calculate):
  34. replace1 = re.search('-[0-9.]+/-',calculate).group()
  35. replace = replace1.replace('/-','/')
  36. replace = replace.replace('-','+')
  37. calculate = calculate.replace(replace1,replace)
  38. elif re.search('\+[0-9.]+/-',calculate):
  39. replace1 = re.search('\+[0-9.]+/-', calculate).group()
  40. replace = replace1.replace('/-', '/')
  41. replace = replace.replace('+', '-')
  42. calculate = calculate.replace(replace1, replace)
  43. while '/' in calculate:
  44. if re.findall('^-[0-9.]+/[0-9.]+',calculate):
  45. division = re.findall('-[0-9.]+/[0-9.]+',calculate)[0]
  46. result = re.findall('(-[0-9.]+)/([0-9.]+)',division)[0]
  47. result = float(result[0])/float(result[1])
  48. calculate = calculate.replace(division,str(result))
  49. else:
  50. division = re.findall('[0-9.]+/[0-9.]+',calculate)[0]
  51. result = re.findall('([0-9.]+)/([0-9.]+)',division)[0]
  52. result = float(result[0])/float(result[1])
  53. calculate = calculate.replace(division,str(result))
  54. while '*' in calculate:
  55. if re.findall('^-[0-9.]+\*[0-9.]+', calculate):
  56. multiplication = re.findall('-[0-9.]+\*[0-9.]+',calculate)[0]
  57. result = re.findall('(-[0-9.]+)\*([0-9.]+)',multiplication)[0]
  58. result = float(result[0])*float(result[1])
  59. calculate = calculate.replace(multiplication,str(result))
  60. else:
  61. multiplication = re.findall('[0-9.]+\*[0-9.]+', calculate)[0]
  62. result = re.findall('([0-9.]+)\*([0-9.]+)', multiplication)[0]
  63. result = float(result[0]) * float(result[1])
  64. calculate = calculate.replace(multiplication, str(result))
  65. return calculate
  66.  
  67. # 定义一个处理只有加减法的函数
  68. def addition_subtraction(calculate):
  69. if '+-' in calculate:
  70. calculate = calculate.replace('+-','-')
  71. elif '--' in calculate:
  72. calculate = calculate.replace('--','+')
  73. list_number = []
  74. list_number_ = re.findall('[+-]?[0-9.]+',calculate)
  75. for i in list_number_:
  76. list_number.append(float(i))
  77. return sum(list_number)
  78.  
  79. # 找到最里面的括号,并传给前面的乘除法运算和加减法运算,得到最终的结果
  80. def final(x):
  81. while '(' in x:
  82. process = re.findall('\(([^()]+)\)',x)
  83. for calculate in process:
  84. y = multiplication_division(calculate)
  85. y = addition_subtraction(y)
  86. x = x.replace('('+calculate+')',str(y))
  87. x = multiplication_division(x)
  88. return addition_subtraction(x)
  89. print(final(x))
  90. ```

  

python 正则的使用 —— 编写一个简易的计算器的更多相关文章

  1. day-1 用python编写一个简易的FTP服务器

    从某宝上购买了一份<Python神经网络深度学习>课程,按照视频教程,用python语言,写了一个简易的FTP服务端和客户端程序,以前也用C++写过聊天程序,编程思路差不多,但是pytho ...

  2. 基于OpenGL编写一个简易的2D渲染框架-06 编写一个粒子系统

    在这篇文章中,我将详细说明如何编写一个简易的粒子系统. 粒子系统可以模拟许多效果,下图便是这次的粒子系统的显示效果.为了方便演示,就弄成了一个动图. 图中,同时显示了 7 种不同粒子效果,看上去效果挺 ...

  3. C#编写一个简易的文件管理器

    编写一个简易的文件管理器,通过本次实验,练习 TreeView.ListView 和SplitContainer 控件的使用,同时熟悉 C#文件系统的操作方法以及 File 类和 Directory类 ...

  4. iOS:制作一个简易的计算器

    初步接触视图,制作了一个简易的计算器,基本上简单的计算是没有问题的,不是很完美,可能还有一些bug,再接再厉. // // ViewController.m // 计算器 // // Created ...

  5. Python Django 编写一个简易的后台管理工具4-添加admin模版

    导入admin后台模版 可以在网上任意搜索模版,我这里也提供一个地址github 拷贝admin后台的html文件至项目的templates文件夹 创建static文件夹,将admin后台的js,im ...

  6. 用Java语言编写一个简易画板

    讲了三篇概博客的概念,今天,我们来一点实际的东西.我们来探讨一下如何用Java语言,编写一块简易的画图板. 一.需求分析 无论我们使用什么语言,去编写一个什么样的项目,我们的第一步,总是去分析这个项目 ...

  7. 基于OpenGL编写一个简易的2D渲染框架-01 创建窗口

    最近正在学习OpenGL,我认为学习的最快方法就是做一个小项目了. 如果对OpenGL感兴趣的话,这里推荐一个很好的学习网站 https://learnopengl-cn.github.io/ 我用的 ...

  8. 使用KVM的API编写一个简易的AArch64虚拟机

    参考资料: Linux虚拟化KVM-Qemu分析(一) Linux虚拟化KVM-Qemu分析(二)之ARMv8虚拟化 Linux虚拟化KVM-Qemu分析(三)之KVM源码(1) Linux虚拟化KV ...

  9. 基于OpenGL编写一个简易的2D渲染框架-03 渲染基本几何图形

    阅读文章前需要了解的知识,你好,三角形:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/ 要 ...

随机推荐

  1. 一款超好用轻量级JS框架——Zepto.js(上)

       前  言 絮叨絮叨 之前我们介绍过JQuery怎么自定义一个插件,但没有详细介绍过JQuery,那么今天呢....我们还是不说JQuery,哈哈哈哈 但是今天我们介绍一款和JQuery超级像的一 ...

  2. 在ssm框架中前后台数据交互均使用json格式

    前后台数据交互均使用json. 框架ssm(spring+springmvc+mybatis) @RequestBody注解实现接收http请求的json数据,将json数据转换为java对象,注解加 ...

  3. Browsing contexts 浏览器上下文

    浏览上下文就是document object 呈现给用户的所在的环境   每一个标签或者窗口都包含一个浏览器上下文,包括iframe   frames      每一个browsing context ...

  4. 分布式框架Dubbo入门

    Dubbo简介 Dubbo是一个Alibaba开源额分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.dubbo就是个服务框架,只有在分布式的时候,才有dubb ...

  5. Robotframework-Appium系列:安装配置

    1.   Robotframework-android系列:安装配置 1.1. 安装环境 64位win10家庭中文版 1.1. 安装说明 网上robotframework-appium安装资料也不少, ...

  6. maven构建SSM--pox.mxl

    最近在做项目,把maven构建SSM的pom.xml文件内容小结一下: 在console中输入如下内容,使用maven创建java web项目: mvn archetype:generate -Dgr ...

  7. Ubuntu & Docker & Consul & Fabio & ASP.NET Core 2.0 微服务跨平台实践

    相关博文: Ubuntu 简单安装 Docker Mac OS.Ubuntu 安装及使用 Consul Consul 服务注册与服务发现 Fabio 安装和简单使用 阅读目录: Docker 运行 C ...

  8. selenium3.7+ python3 添加cookie模拟登陆

    一.背景介绍 最近做一个爬虫项目,用selenium调用浏览器去获取渲染后的源码,但是每次登陆都需要手机验证,这真的是头痛啊,这种验证方式不要想着去破解,还是老老实实用手机收验证码去吧!反正我是不知道 ...

  9. netty(三) 组件介绍

    netty各组件说明:channel ----- SocketEventLoop -------控制流,多线程处理,并发channelFuture ------- 异步通知 channel:主要是实现 ...

  10. Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: Access denied

    装了fedora23后定时关机:sudo shutdown -h +60 弹出如下信息后立刻就关机了: Failed to call ScheduleShutdown in logind, proce ...