Python之re模块

正则就是用一些具有特殊含义的符号组合到一起来描述字符或字符串的方法,它能帮助我们方便的检查一个字符串是否与某种模式匹配。

import re

re.match(pattern, string, flags=0)
# 从开始位置开始匹配,如果开头没有则无,返回None。需要使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

re.search(pattern, string, flags=0) 
# re.search 扫描整个字符串并返回第一个成功的匹配。没有找到则返回None。需要使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

# re.match和re.search的区别在于:
# re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配,找不到也返回None。

re.findall(pattern, string, flags=0) 
#搜索整个字符串,返回一个list

re.finditer(pattern, string, flags=0)
#在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

 

检索和替换

import re
 
phone = "2004-959-559 # 这是一个国外电话号码"
 
# 删除字符串中的 Python注释 
num = re.sub(r'#.*$', "", phone)
print("电话号码是: ", num)
 
# 删除非数字(-)的字符串 
num = re.sub(r'\D', "", phone)
print("电话号码是 : ", num)

 

re.compile 函数

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。

语法:

re.compile(pattern[, flags])

 

re.split函数

re.split(pattern, string[, maxsplit=0, flags=0])
#split 方法按照能够匹配的子串将字符串分割后返回列表。

 

正则表达式对象

re.RegexObjectre.compile() 返回 RegexObject 对象。

re.MatchObject
group() 返回被 RE 匹配的字符串。

**start() 返回匹配开始的位置
**end() 返回匹配结束的位置
**span() 返回一个元组包含匹配 (开始,结束) 的位置

 

 计算器代码实现:

  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 """
  4 该计算器思路:
  5     1、递归寻找表达式中只含有 数字和运算符的表达式,并计算结果
  6     2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数
  7 使用技术:
  8     1、正则表达式
  9     2、递归
 10  
 11 执行流程如下:
 12 ******************** 请计算表达式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) ********************
 13 before: ['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
 14 -40.0/5=-8.0
 15 after: ['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
 16 ========== 上一次计算结束 ==========
 17 before: ['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
 18 9-2*5/3+7/3*99/4*2998+10*568/14=173545.880953
 19 after: ['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']
 20 ========== 上一次计算结束 ==========
 21 before: ['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']
 22 60-30+-8.0*173545.880953=-1388337.04762
 23 after: ['1-2*(-1388337.04762-(-4*3)/(16-3*2))']
 24 ========== 上一次计算结束 ==========
 25 before: ['1-2*(-1388337.04762-(-4*3)/(16-3*2))']
 26 -4*3=-12.0
 27 after: ['1-2*(-1388337.04762--12.0/(16-3*2))']
 28 ========== 上一次计算结束 ==========
 29 before: ['1-2*(-1388337.04762--12.0/(16-3*2))']
 30 16-3*2=10.0
 31 after: ['1-2*(-1388337.04762--12.0/10.0)']
 32 ========== 上一次计算结束 ==========
 33 before: ['1-2*(-1388337.04762--12.0/10.0)']
 34 -1388337.04762--12.0/10.0=-1388335.84762
 35 after: ['1-2*-1388335.84762']
 36 ========== 上一次计算结束 ==========
 37 我的计算结果: 2776672.69524
 38 """
 39  
 40  
 41 import re
 42  
 43  
 44 def compute_mul_div(arg):
 45     """ 操作乘除
 46     :param expression:表达式
 47     :return:计算结果
 48     """
 49  
 50     val = arg[0]
 51     mch = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val)
 52     if not mch:
 53         return
 54     content = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val).group()
 55  
 56     if len(content.split('*'))>1:
 57         n1, n2 = content.split('*')
 58         value = float(n1) * float(n2)
 59     else:
 60         n1, n2 = content.split('/')
 61         value = float(n1) / float(n2)
 62  
 63     before, after = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val, 1)
 64     new_str = "%s%s%s" % (before,value,after)
 65     arg[0] = new_str
 66     compute_mul_div(arg)
 67  
 68  
 69 def compute_add_sub(arg):
 70     """ 操作加减
 71     :param expression:表达式
 72     :return:计算结果
 73     """
 74     while True:
 75         if arg[0].__contains__('+-') or arg[0].__contains__("++") or arg[0].__contains__('-+') or arg[0].__contains__("--"):
 76             arg[0] = arg[0].replace('+-','-')
 77             arg[0] = arg[0].replace('++','+')
 78             arg[0] = arg[0].replace('-+','-')
 79             arg[0] = arg[0].replace('--','+')
 80         else:
 81             break
 82  
 83     if arg[0].startswith('-'):
 84         arg[1] += 1
 85         arg[0] = arg[0].replace('-','&')
 86         arg[0] = arg[0].replace('+','-')
 87         arg[0] = arg[0].replace('&','+')
 88         arg[0] = arg[0][1:]
 89     val = arg[0]
 90     mch = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val)
 91     if not mch:
 92         return
 93     content = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val).group()
 94     if len(content.split('+'))>1:
 95         n1, n2 = content.split('+')
 96         value = float(n1) + float(n2)
 97     else:
 98         n1, n2 = content.split('-')
 99         value = float(n1) - float(n2)
100  
101     before, after = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val, 1)
102     new_str = "%s%s%s" % (before,value,after)
103     arg[0] = new_str
104     compute_add_sub(arg)
105  
106  
107 def compute(expression):
108     """ 操作加减乘除
109     :param expression:表达式
110     :return:计算结果
111     """
112     inp = [expression,0]
113  
114     # 处理表达式中的乘除
115     compute_mul_div(inp)
116  
117     # 处理
118     compute_add_sub(inp)
119     if divmod(inp[1],2)[1] == 1:
120         result = float(inp[0])
121         result = result * -1
122     else:
123         result = float(inp[0])
124     return result
125  
126  
127 def exec_bracket(expression):
128     """ 递归处理括号,并计算
129     :param expression: 表达式
130     :return:最终计算结果
131     """
132     # 如果表达式中已经没有括号,则直接调用负责计算的函数,将表达式结果返回,如:2*1-82+444
133     if not re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression):
134         final = compute(expression)
135         return final
136     # 获取 第一个 只含有 数字/小数 和 操作符 的括号
137     # 如:
138     #    ['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
139     #    找出:(-40.0/5)
140     content = re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression).group()
141  
142     # 分割表达式,即:
143     # 将['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
144     # 分割更三部分:['1-2*((60-30+(    (-40.0/5)      *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
145     before, nothing, after = re.split('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression, 1)
146  
147     print 'before:',expression
148     content = content[1:len(content)-1]
149  
150     # 计算,提取的表示 (-40.0/5),并活的结果,即:-40.0/5=-8.0
151     ret = compute(content)
152  
153     print '%s=%s' %( content, ret)
154  
155     # 将执行结果拼接,['1-2*((60-30+(      -8.0     *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
156     expression = "%s%s%s" %(before, ret, after)
157     print 'after:',expression
158     print "="*10,'上一次计算结束',"="*10
159  
160     # 循环继续下次括号处理操作,本次携带者的是已被处理后的表达式,即:
161     # ['1-2*((60-30+   -8.0  *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
162  
163     # 如此周而复始的操作,直到表达式中不再含有括号
164     return exec_bracket(expression)
165  
166  
167  
168 # 使用 __name__ 的目的:
169 #   只有执行 python index.py 时,以下代码才执行
170 #   如果其他人导入该模块,以下代码不执行
171 if __name__ == "__main__":
172     #print '*'*20,"请计算表达式:", "1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )" ,'*'*20
173     #inpp = '1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) '
174     inpp = "1-2*-30/-12*(-20+200*-3/-200*-300-100)"
175     #inpp = "1-5*980.0"
176     inpp = re.sub('\s*','',inpp)
177     # 表达式保存在列表中
178     result = exec_bracket(inpp)
179     print result
View Code

 

posted @ 2018-06-28 21:32  桥前石头  阅读(405)  评论(0)    收藏  举报