【Python】使用正则表达式实现计算器练习

已知有以下这样一个不太友好的公式:

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

我们使用正则表达式的基础来练习,将此结果计算出来。

代码如下:

  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3
  4 import re
  5 import functools
  6
  7 def minus_operator_handler(formula):
  8     ‘‘‘处理一些特殊的减号运算‘‘‘
  9     minus_operators = re.split("-",formula)
 10     calc_list = re.findall("[0-9]",formula)
 11     if minus_operators[0] == ‘‘:    # 第一个值肯定是负号
 12         calc_list[0] = ‘-%s‘ % calc_list[0]
 13     result = functools.reduce(lambda x,y: float(x) - float(y),calc_list)
 14     print(" - [%s] of result is : " % formula, result )
 15     return result
 16
 17 def handle_minus_in_list(operator_list,calc_list):
 18     ‘‘‘
 19     有的时候把算术符和值分开后,会出现这种情况  [‘-‘, ‘-‘, ‘-‘] [‘ ‘, ‘14969037.996825399 ‘, ‘ ‘, ‘12.0/ 10.0 ‘]
 20     这需要把第2个列表中的空格都变成负号并与其后面的值拼起来
 21     ‘‘‘
 22     for index,item in enumerate(calc_list):
 23         if item == ‘‘:
 24             calc_list[index+1] = item + calc_list[index+1].strip()
 25
 26 def compute_mutiply_and_dividend(formula):
 27     ‘‘‘计算乘除的内容,这里传进来的是字符串‘‘‘
 28     # 找出所有带*、/符号的内容
 29     operators = re.findall("[*/]",formula)
 30     # 以*、/为分隔符,取出所有排除掉*、/的内容
 31     calc_list = re.split("[*/]",formula)
 32     # 结果初始化未None
 33     result = None
 34     # 遍历显示数组中的索引号(index)、内容(i)
 35     for index,i in enumerate(calc_list):
 36         if result:    # 代表不是第一次循环
 37             if operators[index-1] == "*":
 38                 result *= float(i)
 39             elif operators[index-1] == "/":
 40                 result /= float(i)
 41         else:
 42             result = float(i)
 43     print("[%s] of result is : " %formula, result)
 44     return result
 45
 46 def handle_special_occactions(plus_and_minus_operators,multiply_and_dividend):
 47     ‘‘‘有时会出现这种情况 , [‘-‘, ‘-‘] [‘1 ‘, ‘ 2 * ‘, ‘14969036.7968254‘],2*...后面这段实际是 2*-14969036.7968254,需要特别处理下‘‘‘
 48     # 遍历显示数组multiply_and_dividend中的索引号(index)、内容(i)
 49     for index,i in enumerate(multiply_and_dividend):
 50         # 清除空格、空白
 51         i = i.strip()
 52         # 如果 内容的结尾是*、/
 53         if i.endswith("*") or i.endswith("/"):
 54             multiply_and_dividend[index] = multiply_and_dividend[index] + plus_and_minus_operators[index] + multiply_and_dividend[index+1]
 55             del multiply_and_dividend[index+1]
 56             del plus_and_minus_operators[index]
 57     return plus_and_minus_operators,multiply_and_dividend
 58
 59 def remove_addsubtract(formula):
 60     ‘‘‘将加减组合的符号替换成合并后的符号‘‘‘
 61     formula = formula.replace("++","+")
 62     formula = formula.replace("--","+")
 63     formula = formula.replace("+-","-")
 64     formula = formula.replace("-+","-")
 65     formula = formula.replace("- -","+")
 66     return formula
 67
 68 def compute(formula):
 69     ‘‘‘这里计算不带括号的内容‘‘‘
 70     # 去掉外层的括号
 71     formula = formula.strip("()")    # strip是去除的函数
 72     # 将加减组合的符号替换成合并后的符号
 73     formula = remove_addsubtract(formula)
 74     # 找出替换后剩余的所有带+、-符号的内容
 75     plus_and_minus_operators = re.findall("[+-]",formula)
 76     # 以+、-为分隔符,取出所有排除掉+、-的内容,即取出所有*/的内容
 77     multiply_and_dividend = re.split("[+-]",formula)
 78     if len(multiply_and_dividend[0].strip()) == 0:    # 代表这肯定是个减号
 79         multiply_and_dividend[1] = plus_and_minus_operators[0] + multiply_and_dividend[1]
 80         del multiply_and_dividend[0]
 81         del plus_and_minus_operators[0]
 82     plus_and_minus_operators,multiply_and_dividend = handle_special_occactions(plus_and_minus_operators,multiply_and_dividend)
 83     # 遍历显示数组multiply_and_dividend中的索引号(index)、内容(i)
 84     for index,i in enumerate(multiply_and_dividend):
 85         if re.search("[*/]",i):
 86             calc_inside_result = compute_mutiply_and_dividend(i)
 87             multiply_and_dividend[index] = calc_inside_result
 88
 89     ‘‘‘开始运算+、-‘‘‘
 90     print(multiply_and_dividend,plus_and_minus_operators)
 91     total_result = None    # 初始化total_result
 92     # 遍历显示数组multiply_and_dividend中的索引号(index)、内容(item)
 93     for index,item in enumerate(multiply_and_dividend):
 94         if total_result:    # 代表不是第一次循环
 95             if plus_and_minus_operators[index-1] == "+":
 96                 total_result += float(item)
 97             elif plus_and_minus_operators[index-1] == "-":
 98                 total_result -= float(item)
 99         else:
100             total_result = float(item)
101     print("[%s] of result is : " %formula,total_result)
102     return total_result
103
104 def calc(formula):
105     ‘‘‘计算程序主入口, 主要逻辑是先计算括号里的值,算出来后再算乘除,再算加减‘‘‘
106     #给括号的状态设置初始值,假定括号存在
107     parenthesis_flag = True
108     #初始化运算结果为None,还没开始运算
109     calc_result = None
110     while parenthesis_flag:
111         #找到最里面一层的括号。正则表达式:()中间没有()的所有字符
112         inside = re.search("\([^()]*\)",formula)
113         if inside:
114             # 先计算括号里面的值
115             calc_inside_result = compute(inside.group())
116             formula = formula.replace(inside.group(),str(calc_inside_result))
117         else:
118             print(‘\033[41;1m~~~没括号了~~~\033[0m‘)
119             print(‘The End Result is : ‘,compute(formula))
120             # 公式中的括号都被剔除了
121             parenthesis_flag = False
122
123 #程序的入口
124 if __name__ == ‘__main__‘:
125     result = calc("1 - 2 * ( (60-30 +(-9-2-5-2*3-5/3-40*4/2-3/5+6*3) * (-9-2-5-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )")
时间: 2024-08-05 17:53:43

【Python】使用正则表达式实现计算器练习的相关文章

[ Python - 6 ] 正则表达式实现计算器功能

要求:禁止使用eval函数.参考网上代码如下: #!_*_coding:utf-8_*_ """用户输入计算表达式,显示计算结果""" import re a = '2+(6/3-2+(1*4))' # 取最内层的括号 bracket = re.compile('\([^()]+\)') # 加法 add = re.compile('(-?\d+\.?\d*\+\d+\.?\d*)|(-?\d+\.?\d*\+-\d+\.?\d*)') # 减法

python--------re 正则表达式(计算器)

re是一门小型语言 元字符 .      通配符除了\n ^     以什么开始的匹配 $     以什么结尾的匹配 *     重复前一个条件,最少0个,[0,∞] +     重复前一个条件,最少1个,[1,∞] ?   重复前面的条件,最少0个,最多1个[0,1] {x}  重复前面的x次,x为数字,{x,y}最少x次,最多y-1次,{x,}最少x次,最多不限 |     或的意思 \ 反斜杠后跟元字符去除特殊功能 \. 就是匹配点. \+ 匹配+ \\\\ 匹配\ 等于 r"\\&quo

python 中正则表达式

. 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配字符串的开始 $ 匹配字符串的结束 代码/语法 说明 * 重复零次或更多次 + 重复一次或更多次 ? 重复零次或一次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次 [aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!). [0-9]代表的含意与\d就是完全一致的:一位数字:同理[a-z0-9A-Z_]也完

python用正则表达式怎么查询unicode码字符

import re data = open('a.txt') fh = open('b.txt', 'w') """Search the string begining with '['""" p = re.compile(r'\s*[\u3010]') for each_d in data: if re.match('\s*3\d{4}', each_d): each_d = each_d.strip() print(each_d + ': '

【python】正则表达式

在python中,所有和正则表达式相关的功能都包含在re模块中. $表示字符串的末尾,^表示字符串的开始,原始字符串:字符串添加前缀r,表示字符串中的所有字符都不转义.\b表示单词的边界必须在这里. s="100 BROAD" re.sub('ROAD$','RD',s) 结果:'100 BRD' re.sub(r'\bROAD$','RD',s) 结果:100 BROAD M?可选地匹配单个字符,要么一个M,要么没有M.re模块的关键是一个search函数,该函数由两个参数,一个是正

python使用正则表达式文本替换

2D客户端编程从某种意义上来讲就是素材组织,所以,图片素材组织经常需要批量处理,python一定是最佳选择,不过是win/linux/mac都有一个简单的运行环境 举两个应用场景: 如果不是在某个文件夹里面则将文件夹名称插入前面 所有的文件名名称加上一个前缀 直接看代码吧 # encoding: UTF-8 import re # 将正则表达式编译成Pattern对象 p = re.compile(r'(?P<folder>(\w+/)*)(?P<filename>\w+\.png

Python使用正则表达式替换源码前序号

从博客园或其它地方拷贝代码,经常前面有代码序号,像下面这个样子: 1 wbContent.Navigate(vURL); 2  3     Result:=GetHtml(wbContent); 4  5     while not ContainsText(Result,'共找到') do 6     begin 7       Sleep(100); 8       Application.ProcessMessages; 9       Result:=GetHtml(wbContent)

python study - 正则表达式

第 7 章 正则表达式 7.1. 概览 7.2. 个案研究:街道地址 7.3. 个案研究:罗马字母 7.3.1. 校验千位数 7.3.2. 校验百位数 7.4. 使用 {n,m} 语法 7.4.1. 校验十位数和个位数 7.5. 松散正则表达式 7.6. 个案研究:解析电话号码 7.7. 小结 正则表达式是搜索.替换和解析复杂字符模式的一种强大而标准的方法.如果你曾经在其他语言 (如 Perl) 中使用过它,由于它们的语法非常相似,你仅仅阅读一下 re 模块的摘要,大致了解其中可用的函数和参数就

基于Tkinter用50行Python代码实现简易计算器

Tkinter一般是python自带的,所以代码不需要其他组件,本程序是在python2.7版本实现的. 主要涉及了tkinter的使用,函数定义和调用,匿名函数的使用,类成员函数定义等python基础知识,适合新手学习. 代码如下: from Tkinter import * #创建横条型框架 def frame(root, side): w = Frame(root) w.pack(side = side, expand = YES, fill = BOTH) return w #创建按钮

Python爬虫-正则表达式

正则表达式 只提取关注的数据,进行数据赛选 原子: 基本组成单位 普通的字符 非打印支付 通用字符 普通的字符 >>> import re >>> pat="yue" >>> string="http://yum.iqianyue.com" >>> rst1=re.search(pat,string) >>> print(rst1) <_sre.SRE_Match obj