在Python中使用正则表达式的方法


Posted in Python onAugust 13, 2015

正则表达式(regular expression)是一种用形式化语法描述的文本匹配模式。在需要处理大量文本处理的应用中有广泛的使用,我没使用的编辑器,IDE中的搜索常用正则表达式作为搜索模式。玩过*nix系统的都知道如sed,grep,awk这类的命令,他们是非常强大的文本处理工具。几乎所有的语言都有对正则表达式的支持,有的直接在语法中支持,有的使用扩展库的形式。python使用的就是扩展库re。

    re.search(pattern,string,flag=0)

    搜索文本中的匹配的模式是最常用的.以模式和文本作为输入,如果有匹配则返回一个Match对象,反之返回None。
    每个Match对象包括相关的匹配信息:原字符串、正则表达式和匹配的文本在字符串中的位置。
import re 
pattern = "this" 
text = "Does this text match the pattern?" 
match = re.search(pattern, text) # 返回一个Match对象 
print match.re.pattern # 要匹配的正则表达式"this"
print match.string   # 匹配的文本"Does this match the pattern?" 
print match.start()   # 匹配的开始位置 5
print match.end()    # 匹配的结束位置 9

    re.compile(pattern,flag=0)
    如果程序中频繁的使用到同一个正则表达式,每次使用的时候都写一遍正则表达式不仅不高效而且会大大增加出错的几率,re提供了compile函数将一个表达式字符串编译为一个RegexObject。
    模块级函数会维护已编译表达式的一个缓存,而这个缓存是的大小是有限制的。直接使用已经编译的表达式可以避免缓存查找的开销,并且在加载模块时就会预编译所有的表达式。

import re 
regex = re.compile("this") 
text = "Does this text match the pattern?" 
match = regex.search(text) 
if match: 
  print "match" 
  match.group(0)  #返回匹配的字符串  
else:
  print "not match"

    re.findall(pattern, string, flag=0)
    使用search会返回匹配的单个实例,使用findall会返回所有匹配的不重叠的子串。

import re 
pattern = 'ab' 
text = 'abbaaabbbbaaaaaa' 
re.findall(pattern, text)  # 返回['ab', 'ab']

    re.finditer(pattern, string, flag=0)
    finditer会返回一个迭代器,会生成Match实例,不像findall()返回字符串.

import re 
pattern = 'ab' 
text = 'abbaaabbbbaaaaaa' 
match = re.finditer(pattern, text)  
for m in match:
  print m.start() 
  print m.end()

以上的例子会分别输出两次匹配结果的起始位置和结束位置。

正则匹配默认采用的是贪婪算法,也就是说会re在匹配的时候会利用尽可能多的输入,而使用?可以关闭这种贪心行为,只匹配最少的输入。这之前先说下量词。

量词是为了简化正则表达式的读写而定义的,通用的形式是{m,n},这表示匹配的个数至少是m,最多是n,在','之后不能有空格,否则会出错,并且均为闭区间。

  •     {n} 之前的元素必须出现n次
  •     {m,n} 之前元素最少出现m次,最多n次
  •     {m,} 之前的元素最少出现m次,无上限
  •     {0,n} 之前的元素可以不出现,也可以出现,出现的话最多出现n次

除了之上,还有三个常用的量词*,?和+

  •     * 等价于{0,}
  •     + 等价于{1,}
  •     \? 等价于{0,1}

还有^和$,分别表示段或者字符串的开始与结束。

import re 
re.search("^travell?er$", "traveler")  # True 
re.search("^travell?er$", "traveller")  # True  
re.search("^ab\*", "abbbbbbb")      # True,返回"abbbbbbb" 
re.search("^ab\*?", "abbbbbbb")     # True,返回"a" 
re.search("^ab+", "abbbbbbb")      # True,返回"abbbbbbb" 
re.search("^ab+?", "abbbbbbb")      # True,返回"ab"

对于一些预定义的字符集可以使用转义码可以更加紧凑的表示,re可以识别的转义码有3对,6个,分别为三个字母的大小写,他们的意义是相反的。

  •     \d : 一个数字
  •     \D : 一个非数字
  •     \w : 字母或者数字
  •     \W : 非字母,非数字
  •     \s : 空白符(制表符,空格,换行符等)
  •     \S : 非空白符

如果想指定匹配的内容在文本的相对位置,可以使用锚定,跟转义码类似。

  •     ^ 字符或行的开始
  •     $ 字符或行的结束
  •     \A 字符串的开始
  •     \Z 字符串结束
  •     \b 一个单词开头或者末尾的空串
  •     \B 不在一个单词开头或末尾的空串
import re
the_str = "This is some text -- with punctuation" 
re.search(r'^\w+', the_str).group(0)    # This
re.search(r'\A\w+', the_str).group(0)   # This 
re.search(r'\w+\S*$', the_str).group(0)  # punctuation 
re.search(r'\w+\S*\Z', the_str).group(0)  # punctuation 
re.search(r'\w*t\W*', the_str).group(0)  # text -- 
re.search(r'\bt\w+', the_str).group(0)   # text 
re.search(r'\Bt*\B', the_str).group(0)   # 没有匹配

用组来解析匹配,简单的说就是在一个正则表达式中有几个小括号()将匹配的表达式分成不同的组,使用group()函数来获取某个组的匹配,其中0为整个正则表达式所匹配的内容,后面从1开始从左往右依次获取每个组的匹配,即每个小括号中的匹配。使用groups()可以获取所有的匹配内容。

import re 
the_str = "--aabb123bbaa" 
pattern = r'(\W+)([a-z]+)(\d+)(\D+)' 
match = re.search(pattern, the_str)  
match.groups()  # ('--', 'aabb', '123', 'bbaa') 
match.group(0)  # '--aabb123bbaa' 
match.group(1)  # '--' 
match.group(2)  # 'aabb' 
match.group(3)  # '123' 
match.group(4)  # 'bbaa'

python对分组的语法做了扩展,我们可以对每个分组进行命名,这样便可以使用名称来调用。语法:(?P<name>pattern),使用groupdict()可以返回一个包含了组名的字典。

import re 
the_str = "--aabb123bbaa" 
pattern = r'(?P<not_al_and_num>\W+)(?P<al>[a-z]+)(?P<num>\d+)(?P<not_num>\D+)' 
match = re.search(pattern, the_str)  
match.groups()  # ('--', 'aabb', '123', 'bbaa') 
match.groupdict() # {'not_al_and_num': '--', 'not_num': 'bbaa', 'num': '123', 'al': 'aabb'} 
match.group(0)          # '--aabb123bbaa' 
match.group(1)          # '--' 
match.group(2)          # 'aabb' 
match.group(3)          # '123' 
match.group(4)          # 'bbaa'  
match.group('not_al_and_num')  # '--'
match.group('al')         # 'aabb' 
match.group('num')        # '123' '
match.group('not_num')      # 'bbaa'

以上的group()方法在使用的时候需要注意,只有在有匹配的时候才会正常运行,否则会抛错,所以在不能保证有匹配而又要输出匹配结果的时候,必须做校验。

在re中可以设置不通的标志,也就是search()和compile()等中都包含的缺省变量flag。使用标志可以进行完成一些特殊的要求,如忽略大小写,多行搜索等。

import re 
the_str = "this Text" 
re.findall(r'\bt\w+', the_str)  # ['this'] 
re.findall(r'\bt\w+', the_str, re.IGNORECASE) # ['this', 'Text']

 

Python 相关文章推荐
python模拟鼠标拖动操作的方法
Mar 11 Python
在Django中创建URLconf相关的通用视图的方法
Jul 20 Python
Python实现加载及解析properties配置文件的方法
Mar 29 Python
python实现关键词提取的示例讲解
Apr 28 Python
使用Python通过win32 COM实现Word文档的写入与保存方法
May 08 Python
Python判断一个三位数是否为水仙花数的示例
Nov 13 Python
Python-while 计算100以内奇数和的方法
Jun 11 Python
利用rest framework搭建Django API过程解析
Aug 31 Python
python迭代器常见用法实例分析
Nov 22 Python
Python的对象传递与Copy函数使用详解
Dec 26 Python
浅谈cv2.imread()和keras.preprocessing中的image.load_img()区别
Jun 12 Python
python自动获取微信公众号最新文章的实现代码
Jul 15 Python
简单讲解Python中的闭包
Aug 11 #Python
Python实现短网址ShortUrl的Hash运算实例讲解
Aug 10 #Python
python实现web方式logview的方法
Aug 10 #Python
python实现JAVA源代码从ANSI到UTF-8的批量转换方法
Aug 10 #Python
python用10行代码实现对黄色图片的检测功能
Aug 10 #Python
详解Python中dict与set的使用
Aug 10 #Python
分析并输出Python代码依赖的库的实现代码
Aug 09 #Python
You might like
综合图片计数器
2006/10/09 PHP
php下实现在指定目录搜索指定类型文件的函数
2008/10/03 PHP
php获取英文姓名首字母的方法
2015/07/13 PHP
YII动态模型(动态表名)支持分析
2016/03/29 PHP
php实现的简单中文验证码功能示例
2017/01/03 PHP
PHP 实现base64编码文件上传出现问题详解
2020/09/01 PHP
Prototype Array对象 学习
2009/07/19 Javascript
IE6下拉框图层问题探讨及解决
2014/01/03 Javascript
Javascript中引用示例介绍
2014/02/21 Javascript
js改变鼠标的形状和样式的方法
2014/03/31 Javascript
js加入收藏夹代码(兼容ie/ff/op)
2014/05/16 Javascript
js实现网页右上角滑出会自动消失大幅广告的方法
2015/02/27 Javascript
AngularJS入门教程之AngularJS表达式
2016/04/18 Javascript
Javascript this 函数深入详解
2016/12/13 Javascript
微信小程序实现跟随菜单效果和循环嵌套加载数据
2017/11/21 Javascript
Vue2.0实现调用摄像头进行拍照功能 exif.js实现图片上传功能
2018/04/28 Javascript
layui+SSM的数据表的增删改实例(利用弹框添加、修改)
2019/09/27 Javascript
Vue通过配置WebSocket并实现群聊功能
2019/12/31 Javascript
基于html+css+js实现简易计算器代码实例
2020/02/28 Javascript
javascript实现时钟动画
2020/12/03 Javascript
[02:30]DOTA2放量测试专访海涛:呼吁保护新手玩家
2013/08/26 DOTA
[49:07]VGJ.T vs Optic Supermajor小组赛D组 BO3 第二场 6.3
2018/06/04 DOTA
讲解python参数和作用域的使用
2013/11/01 Python
python开发中module模块用法实例分析
2015/11/12 Python
详解Python中的array数组模块相关使用
2016/07/05 Python
python3.5 + PyQt5 +Eric6 实现的一个计算器代码
2017/03/11 Python
python爱心表白 每天都是浪漫七夕!
2018/08/18 Python
celery4+django2定时任务的实现代码
2018/12/23 Python
python实现简单遗传算法
2020/09/18 Python
python爬虫今日热榜数据到txt文件的源码
2021/02/23 Python
关于环保的建议书
2014/05/12 职场文书
工作目标责任书
2014/07/23 职场文书
委托书的写法
2014/08/30 职场文书
瘦西湖导游词
2015/02/03 职场文书
Pytest之测试命名规则的使用
2021/04/16 Python
彻底卸载VMware虚拟机的超详细步骤记录
2022/07/15 Servers