作业:

使用正则表达式实现计算器功能。

实现:

1、实现带括号的计算

2、实现指数、加减乘除求余等功能

先看运行结果:

 请输入您的计算式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
第 1 选取的()为: ★(-40.0/5)★
选取 乘除 运算第 1 运算式为:★40.0/5★
乘除 运算第 1 运算式的结果为: ★-8.0★
第 1 选取的()计算结果为: ★-8.0★
新的表达式为: 1-2*((60-30-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
第 2 选取的()为: ★(9-2*5/3+7/3*99/4*2998+10*568/14)★
选取 乘除 运算第 1 运算式为:★2*5★
乘除 运算第 1 运算式的结果为: ★9-10.0/3+7/3*99/4*2998+10*568/14★
选取 乘除 运算第 2 运算式为:★10.0/3★
乘除 运算第 2 运算式的结果为: ★9-3.3333+7/3*99/4*2998+10*568/14★
选取 乘除 运算第 3 运算式为:★7/3★
乘除 运算第 3 运算式的结果为: ★9-3.3333+2.3333*99/4*2998+10*568/14★
选取 乘除 运算第 4 运算式为:★2.3333*99★
乘除 运算第 4 运算式的结果为: ★9-3.3333+230.9967/4*2998+10*568/14★
选取 乘除 运算第 5 运算式为:★230.9967/4★
乘除 运算第 5 运算式的结果为: ★9-3.3333+57.7491*2998+10*568/14★
选取 乘除 运算第 6 运算式为:★57.7491*2998★
乘除 运算第 6 运算式的结果为: ★9-3.3333+173131.8018+10*568/14★
选取 乘除 运算第 7 运算式为:★10*568★
乘除 运算第 7 运算式的结果为: ★9-3.3333+173131.8018+5680.0/14★
选取 乘除 运算第 8 运算式为:★5680.0/14★
乘除 运算第 8 运算式的结果为: ★9-3.3333+173131.8018+405.7142★
选取 加减 运算第 1 运算式为:★9-3.3333★
加减 运算第 1 运算式的结果为: ★5.6667+173131.8018+405.7142★
选取 加减 运算第 2 运算式为:★5.6667+173131.8018★
加减 运算第 2 运算式的结果为: ★173137.4685+405.7142★
选取 加减 运算第 3 运算式为:★173137.4685+405.7142★
加减 运算第 3 运算式的结果为: ★173543.1826★
第 2 选取的()计算结果为: ★173543.1826★
新的表达式为: 1-2*((60-30-8.0*173543.1826)-(-4*3)/(16-3*2))
第 3 选取的()为: ★(60-30-8.0*173543.1826)★
选取 乘除 运算第 1 运算式为:★8.0*173543.1826★
乘除 运算第 1 运算式的结果为: ★60-30-1388345.4608★
选取 加减 运算第 1 运算式为:★60-30★
加减 运算第 1 运算式的结果为: ★30.0-1388345.4608★
选取 加减 运算第 2 运算式为:★30.0-1388345.4608★
加减 运算第 2 运算式的结果为: ★-1388315.4608★
第 3 选取的()计算结果为: ★-1388315.4608★
新的表达式为: 1-2*(-1388315.4608-(-4*3)/(16-3*2))
第 4 选取的()为: ★(-4*3)★
选取 乘除 运算第 1 运算式为:★4*3★
乘除 运算第 1 运算式的结果为: ★-12.0★
第 4 选取的()计算结果为: ★-12.0★
新的表达式为: 1-2*(-1388315.4608+12.0/(16-3*2))
第 5 选取的()为: ★(16-3*2)★
选取 乘除 运算第 1 运算式为:★3*2★
乘除 运算第 1 运算式的结果为: ★16-6.0★
选取 加减 运算第 1 运算式为:★16-6.0★
加减 运算第 1 运算式的结果为: ★10.0★
第 5 选取的()计算结果为: ★10.0★
新的表达式为: 1-2*(-1388315.4608+12.0/10.0)
第 6 选取的()为: ★(-1388315.4608+12.0/10.0)★
选取 乘除 运算第 1 运算式为:★12.0/10.0★
乘除 运算第 1 运算式的结果为: ★-1388315.4608+1.2★
选取 加减 运算第 1 运算式为:★-1388315.4608+1.2★
加减 运算第 1 运算式的结果为: ★-1388314.2608★
第 6 选取的()计算结果为: ★-1388314.2608★
新的表达式为: 1-2*-1388314.2608
()选择结束,执行如上最后计算式
选取 乘除 运算第 1 运算式为:★2*-1388314.2608★
乘除 运算第 1 运算式的结果为: ★1+2776628.5216★
选取 加减 运算第 1 运算式为:★1+2776628.5216★
加减 运算第 1 运算式的结果为: ★2776629.5216★
最后的计算结果为: ★2776629.5216★

运行结果

大致思路:

1、匹配模块:

循环匹配最内部括号,匹配后计算结果并替换原字符串

2、计算模块:

循环匹配乘除运算、匹配后计算结果并替换

循环匹配加减运算、匹配后计算结果并替换

3、里面有很多细节要注意如:

检测非法输入、保留四位小数、-号的处理原则等。

源码如下:

 import re
welcome = '''
-------------------------------------
welcome to the counter of lmh
-------------------------------------
'''
def format_s(x): #格式化输出
x = re.sub(r'\s+','',x)
x = re.sub(r'\++|\-\-',r'+',x)
x = re.sub(r'\-\+|\+\-',r'-',x)
x = re.sub(r'\.+',r'.',x)
while True:
x1 = re.search(r'\d+\.\d{5}',x)
if x1 == None:
break
else:
x2 = re.search(r'\d+\.\d{4}',x1.group())
x = re.sub(r'\d+\.\d{5,}',x2.group(),x,1)
return x def islegal(x): #判断输入是否合法
global flag
flag = 0
ret0 = re.search('\.\d+\..*',x)
ret = re.sub(r'\d|\+|\-|\*|\/|\(|\)|\s+|\.+','',x)
if ret0 ==None and ret == '':
pass
else:
print('您的输入不合法请重新输入')
flag = 1 def cal_num(x): #二元计算式算法,x为需要处理的二元字符串
ss = re.search('\D',x)
if ss == None:
return x
else:
s1 = float(re.search('^\-*\d+\.?\d*',x).group()) #选取元素x
s2 = float(re.search('\-*\d+\.?\d*$',x).group()) #选取元素y
sb = re.search(r'\*',x) #匹配二元计算式是否包含元素*
sb2 = re.search(r'/',x) #匹配二元计算式是否包含元素/
sb3 = re.search(r'\+',x) #匹配二元计算式是否包含是否元素+,前面已经格式化。有+号代表选取的二元计算式只能是+法运算
sb4 = re.search('\-*\d+\.?\d*\-\-*\d+\.?\d*',x) #选取元素- 注意:第一个元素可能有负号,因此需要选取左右都为数字的
if sb != None:
s4 = float(s1) * float(s2)
elif sb2 != None:
s4 = float(s1) / float(s2)
elif sb3 != None:
s4 = float(s1) + float(s2)
elif sb4 != None:
s4 = float(s1) + float(s2)
else:
s4 = float(s1)
s5 = str(s4)
return s5 def cal_select(p):#先乘除后加减方法
d = '乘除'
first = re.compile(r'\d+\.*\d*\*\-*\d+\.*\d*|\d+\.*\d*/\-*\d+\.*\d*')#匹配*号或者/前面的数字和后面的数字。注意:前面不匹配-号,后面需要匹配-号
second = re.compile(r'\-*\d+\.*\d*\+\-*\d+\.*\d*|\-*\d+\.*\d*\-\-*\d+\.*\d*')#匹配+号前面的数字和后面的数字。注意:前面匹配-号,后面也需要匹配-号
def cir(x):
i = 1
while True:
nonlocal p
s0 = x.search(p) #选取第一个2元计算式
if s0 == None:
break
s0 = s0.group()
print(' 选取 %s 运算第 %s 运算式为:★%s★'%(d,i,s0))
p = re.sub(x, cal_num(s0), p,count=1)
p = format_s(p)
print(' %s 运算第 %s 运算式的结果为: ★%s★'%(d,i,p))
i += 1
cir(first)
d = '加减'
cir(second)
p = format_s(p)
return p while True:#判断输入合法性
print(welcome)
s = input(r'请输入您的计算式: ')
islegal(s)
if flag == 1:
continue
else:
break
s = format_s(s) i=1
while True:#依次匹配最内部()
find_parentheses = re.compile(r'\([^()]*\)') #匹配最内部(..)方法
clear_parentheses = re.compile('\(|\)') #只匹配()方法
ret = find_parentheses.search(s) #匹配字符串s最内部括号
if ret == None:
break
s0 = clear_parentheses.sub('',ret.group()) #取消字符串s最内部括号,保留内部计算式s0
print('第 %s 选取的()为: ★%s★'%(i,ret.group()))
s5 = cal_select(s0) #计算s0结果
print('第 %s 选取的()计算结果为: ★%s★'%(i,s5))
s = re.sub(find_parentheses,s5,s,count=1) #替换在s字符串中替换so
s = format_s(s) #刷新格式
print('新的表达式为: %s'%s)
i += 1 print('()选择结束,执行如上最后计算式')
s = cal_select(s)
print('最后的计算结果为: ★%s★'%s)

counter

最新文章

  1. J2EE项目开发中常用到的公共方法
  2. 关于bootstrap和响应式布局
  3. 泛型容器单元(Generics.Collections)[2]: TQueue<T> 队列列表
  4. NXP开源自动驾驶计算平台Bluebox 打造现实无人汽车
  5. Visual Studio VS2010统计代码行数(转载)
  6. HIP-HOP 漫画家 Skottie Young
  7. Python基础学习笔记(七)常用元组内置函数
  8. firework便捷截LOGO
  9. php 解压 .gz 文件
  10. python写的多线程下载工具
  11. Book for Opencv
  12. Freemarker常用技巧(一)
  13. Asp.net 网站出现Service Unavailable 问题剖析
  14. TortoiseGit安装与配置(转)
  15. JS读写浏览器cookie及读取页面参数
  16. KVM 虚拟机 安装配置
  17. PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】
  18. mac 开发环境安装
  19. arcgis api 3.x for js入门开发系列九热力图效果(附源码下载)
  20. sqlserver数据库方面的排序四大王

热门文章

  1. redis键操作
  2. iozone测试磁盘性能
  3. python交互模式下tab键自动补全
  4. linux 搭建PPTP
  5. java 如何将 word,excel,ppt如何转pdf --openoffice (1)
  6. FreeMarker template error: The following has evaluated to null or missing: ==> blogger.md [in template "admin/about.ftl" at line 44, column 84]
  7. Java内存回收机制基础[转]
  8. Python基础篇(四)
  9. FileBeat安装配置
  10. Dapper入门教程(二)——执行非查询语句