Python 3.x--使用re模块,实现计算器运算实例

要求:使用re模块,通过正则表达式,实现计算器运算功能。

思路:1、匹配函数中最内层的括号,提取函数使用re.search,先计算乘除,后计算加减,注意针对正负号的处理,使用re.split,可以截取函数前后的部分,重新拼接结果。

   2、加减、乘除及去括号单独写函数调用

具体代码:

  1 import re
  2
  3 #乘除运算处理,可以处理不含括号的加减和乘除函数(只处理乘除)
  4 def multi_and_divi(arg):
  5     #传入参数为列表,如:[‘3*2-1*9/3‘,0]
  6     val = arg[0]
  7     # 对字符串进行乘除匹配:如3*2-1*9/3,就匹配:3*2
  8     mch = re.search(‘\d+\.?\d*[\*\/]+[\+\-]?\d+\.?\d*‘, val)
  9     if not mch:    #mch为空,没有匹配
 10         return
 11     # 将匹配到的内容保存在content中
 12     content = re.search(‘\d+\.?\d*[\*\/]+[\+\-]?\d+\.?\d*‘,val).group()
 13     #print(‘>>>>>>>>‘,content)
 14     # 对匹配到的内容进行*、/判断,然后进行相应的计算,如2*3,先分割后计算
 15     if len(content.split(‘*‘)) > 1:
 16         n1,n2 = content.split(‘*‘)
 17         value = float(n1)*float(n2)
 18     elif len(content.split(‘/‘)) > 1:
 19         n1,n2 = content.split(‘/‘)
 20         value = round(float(n1)/float(n2),8)
 21     # 取出匹配内容两头的内容:before,after
 22     before,after = re.split(‘\d+\.?\d*[\*\/]+[\+\-]?\d+\.?\d*‘,val,1)
 23     # 拼接成新的字符串
 24     new_str = "%s%s%s" % (before, value, after)
 25     # 把new_str赋值到arg[0]中
 26     arg[0] = new_str
 27     #print(arg)
 28     # 再递归进行乘除计算
 29     multi_and_divi(arg)
 30
 31 #multi_and_divi([‘-40/-5-4*+2+2*-3+3*+3‘,0])
 32 #处理后的结果:[‘--8.0-8.0+-6.0+9.0‘, 0]
 33
 34 #加减运算处理
 35 def add_and_substr(arg):
 36     #arg = [‘--8.0-8.0+-6.0+9.0‘, 0]
 37     # 对传进来的arg[0]表达式进行第1次处理,将表达式中的++\--变成+,+-、-+变成-,处理完成以后就直接break
 38     while True:
 39         if arg[0].__contains__(‘++‘) or arg[0].__contains__(‘--‘) or arg[0].__contains__(‘-+‘) or arg[0].__contains__(‘+-‘):
 40             arg[0] = arg[0].replace(‘++‘,‘+‘)
 41             arg[0] = arg[0].replace(‘--‘,‘+‘)
 42             arg[0] = arg[0].replace(‘+-‘,‘-‘)
 43             arg[0] = arg[0].replace(‘-+‘,‘-‘)
 44         else:
 45             break
 46
 47     # 对传进来的arg[0]表达式进行第2次处理,提取首位为“-”,并将提取的次数保存在arg[1]中
 48     # 并且每提取1次:将表达式中的"+"替换成"-"."-"替换成"+",然后取arg[0]表达式字符串中第1到最后1位即可赋给arg[0]
 49     #如:-8-10+19-4 = -(8+10-19+4)
 50     if arg[0].startswith(‘-‘):
 51         arg[1] += 1
 52         arg[0] = arg[0].replace(‘-‘, ‘&‘)   #&8.0&10.0&6.0+9.0
 53         arg[0] = arg[0].replace(‘+‘, ‘-‘)   #&8.0&10.0&6.0-9.0
 54         arg[0] = arg[0].replace(‘&‘, ‘+‘)   #+8.0+10.0+6.0-9.0
 55         arg[0] = arg[0][1:]
 56     value = arg[0]
 57
 58     # 对字符串value进行匹配,匹配加或减两边的内容,如1+2-3,就匹配1+2
 59     mch = re.search(‘\d+\.?\d*[\+\-]+\d+\.?\d*‘,value)
 60     if not mch:
 61         return
 62     content = re.search(‘\d+\.?\d*[\+\-]+\d+\.?\d*‘,value).group()
 63     if len(content.split(‘+‘)) > 1:
 64         n1,n2 = content.split(‘+‘)
 65         get_value = float(n1)+float(n2)
 66     else:
 67         n1,n2 = content.split(‘-‘)
 68         get_value = float(n1)-float(n2)
 69     # 取出匹配内容两头的内容:before,after
 70     before, after = re.split(‘\d+\.?\d*[\+\-]+\d+\.?\d*‘, arg[0], 1)
 71     # 拼接成新的字符串
 72     new_str = "%s%s%s" % (before, get_value, after)
 73     # 把new_str赋值到arg[0]中
 74     arg[0] = new_str
 75     #print(arg)
 76     add_and_substr(arg)
 77
 78 #add_and_substr([‘-8.0-10.0+-6.0+9.0‘, 0])
 79
 80 #计算函数
 81 def compute(sr):
 82     #传入需要计算的函数,如:‘(-40/5-4*2+2*-3+3*3)‘
 83     #去掉括号,组成列表
 84     list_str = [sr.strip(‘()‘), 0]
 85     multi_and_divi(list_str)
 86     add_and_substr(list_str)
 87
 88     # 判断new_str[1]是奇数还是偶数,若是奇数,表明结果为负数,否则为正数
 89     #注:计算加减和乘除的函数没有返回值,可以取出list_str结果,原因解释见最后实例
 90     count = divmod(list_str[1], 2)
 91     result = list_str[0]
 92     if count[1] == 1:
 93         result = float(result) * (-1)
 94     return result
 95
 96 #print(compute(‘-40/5-4*2+2*-3+3*3‘))
 97
 98 #remv_brackets:去括号,只保留最内层函数
 99 def remv_brackets(sr):
100     flag = True
101     while flag:
102         # 匹配最里层“()”及函数,如:1+2*(3/(3-2)*2),这里匹配的是(3-2)
103         i = re.search(‘\([^()]+\)‘,sr)
104         if i:
105             sub_str = i.group()
106             # 调用计算函数,返回值赋值给sub_res
107             sub_res = compute(sub_str)
108             # 将i截取的第一个括号内容替换为转化为str类型的sub_res
109             sr = sr.replace(sub_str,str(sub_res))
110         else:
111             # 如果没有括号了,打印计算函数返回的结果
112             print(‘结果是:‘,compute(sr))
113             flag = False
114
115 if __name__ == ‘__main__‘:
116     print(‘-------------欢迎使用--------------‘)
117     flag = True
118     while flag:
119         sr = input(‘请输入计算函数(q退出):‘)
120         sr = re.sub(‘\s*‘,‘‘,sr)
121         symbol = re.search(‘[0-9q\+\-\/\*]‘,sr)
122         #print(symbol)
123         if not symbol:  #判断symbol为空
124             print(‘输入有误‘)
125             sr = input(‘请重新输入要计算的函数(q:退出):‘)
126             sr = re.sub(‘\s*‘, ‘‘, sr)
127             if sr == ‘q‘:
128                 exit(‘感谢使用,再见‘)
129             else:
130                 remv_brackets(sr)
131         else:
132             if sr == ‘q‘:
133                 exit(‘感谢使用,再见‘)
134             else:
135                 remv_brackets(sr)
136
137 #1-2*((60-30+(-40/5)*(9-2*5/3+ 7/3*99/4*2998+10*568/14)) - (-4*3)/(16-3*2) )

运行结果:

因为list是可变对象,l1传入func时,list1与l1指向的是同一个list,list1执行append,就是l1和list1指向的这同一个list执行了append,然后list1又重新指向了一个新的list,此时不会对原list产生影响。

时间: 2024-10-28 19:55:25

Python 3.x--使用re模块,实现计算器运算实例的相关文章

Python中的元组,字典、计算器代码实例及python2与python3的区别

1.计算器实例 #/usr/bin/env python # -*- coding:utf-8 -*- # @time   :2018/1/22 21:09 # @Author :FengXiaoqing # @file   :jsq.py def add(string):     total = 0     numbers = []     numbers += string.split("+")     for num in numbers:         total += in

python 下的crc16计算模块 XCRC16

又一次突然遇到用python处理modbus通信而需要crc16校验的问题,当时在百度上没找到,在google上找到了一个外国人开发的python包,结果安装好了之后发现校验的不正确(可能是使用的模式串不一样,xcrc16的模式串为0xa001),后来事情过去了就写了一个包弥补一下,xcrc16 的意思是 extend crc->xcrc ,也是我的第一个开源项目,如果大家使用程序遇到什么情况也麻烦通知我下,我会第一时间进行维护. 介绍: xcrc16 模块是为了解决crc16校验问题而写 目前

python小白-day6 time&datetime模块

time&datetime ?一.time模块 time模块提供各种操作时间的函数 说明:一般有两种表示时间的方式:       第一种是时间戳的方式(相对于1970.1.1 00:00:00以秒计算的偏移量),时间戳是惟一的       第二种以数组的形式表示即(struct_time),共有九个元素,分别表示,同一个时间戳的struct_time会因为时区不同而不同 1 2 3 4 5 6 7 8 9 10 11 12 import time print('clock():',time.cl

Python新手必备练习4---开发一个计算器程序

总是有朋友问我,在听我讲的课时感觉都能听懂,我讲的例子照着写也能做出来,但一到自己想不照抄而是自己写的时候,就发现完全没有思路,不知如何下手.对此我只能说,还是因为练习的少,平常从来不写代码,学了点语法就想啪啪啪实现复杂的功能是不现实的,学习语言是一个循序渐近的过程,不经过几万行代码的洗礼,是很难成为一个优秀的程序员的,为了帮助初学者找一些好的练习基本功的例子,我近期会整理我讲课一来的一些Python练习程序分享给大家,想学好Python的同学可以照着例子一一去做,我敢保证,把我列出的练习程序列

python基础学习日志day5-各模块文章导航

python基础学习日志day5---模块使用 http://www.cnblogs.com/lixiang1013/p/6832475.html python基础学习日志day5---time和datetime模块 http://www.cnblogs.com/lixiang1013/p/6848245.html python基础学习日志day5---random模块http://www.cnblogs.com/lixiang1013/p/6849162.html python基础学习日志da

python基础-常用内建模块

一.collections:内建集合模块. 1.namedtuple:创建一个自定义的tuple对象 2.deque:为了高效实现插入和删除操作的双向列表,适合用于队列和栈 3.defaultdict:Key不存在时返回默认值 4.OrderedDict:保持Key的顺序 5.Counter:一个简单的计数器 二.base64 : 一种用64个字符来表示任意二进制数据的方法 三.struct : str和其他二进制数据类型的转换 四.hashlib : 提供常见的摘要算法,如MD5,SHA1 五

Python学习笔记八:模块

模块让你能够有逻辑地组织你的Python代码段. 把相关的代码分配到一个 模块里能让你的代码更好用,更易懂. 模块也是Python对象,具有随机的名字属性用来绑定或引用. 简单地说,模块就是一个保存了Python代码的文件.模块能定义函数,类和变量.模块里也能包含可执行的代码. import 想使用Python源文件,只需在另一个源文件里执行import语句,当解释器遇到import语句,如果模块在当前的搜索路径就会被导入. 1 #coding=utf-8 2 #!/usr/bin/python

python爬虫----(1. 基本模块)

python爬虫,web spider.爬取网站获取网页数据,并进行分析提取. 基本模块使用的是 urllib,urllib2,re,等模块 (一)基本用法,例子 (1)进行基本GET请求,获取网页html #!coding=utf-8 import urllib import urllib2 url = 'http://www.baidu.com/' # 获取请求 request = urllib2.Request(url) try:     # 根据request,得到返回response

Python学习(六)模块

Python 模块 模块定义 随着程序越来越庞大,需要分隔成几个文件:也需要能在不同文件中复用函数.类和变量,而不是拷贝代码.为了满足这些需要,Python提供了模块. 简单地说,模块就是一个保存了Python代码的文件.模块能定义函数,类和变量.模块里也能包含可执行的代码. 模块是包括Python定义和声明的文件.文件名就是模块名加上  .py 后缀.(目前使用Notepad++ 学习而保存的 .py 文件即为模块) 模块的模块名(作为一个字符串)可以由全局变量 __name __ 得到. 例