Python的regex模块——更强大的正则表达式引擎

Python的regex模块——更强大的正则表达式引擎,第1张

Python自带了正则表达式引擎(内置的re模块),但是不支持一些高级特性,比如下面这几个:

固化分组  Atomic grouping 占有优先量词   Possessive quantifiers 可变长度的逆序环视   Variable-length lookbehind 递归匹配  Recursive patterns (起始/继续)位置锚\G  Search anchor

幸好,在2009年,Matthew Barnett写了一个更强大正则表达式引擎——regex模块,这是一个Python的第三方模块。

除了上面这几个高级特性,还有很多有趣、有用的东西,本文大致介绍一下,很多内容取自regex的文档。

无论是编程还是文本处理,regex模块都是一件利器。

用一个指标可以大致了解它的复杂性,re模块有4270行C语言代码,而regex模块有24513行C语言代码。

这个模块以后可能被收进Python标准库。目前(2015年)它还在不断发展,经常发布bug修正版,不过感觉用在一般生产环境应该没什么问题。

目录

一、安装regex

二、一些有趣的特性

三、模糊匹配

四、两种工作模式

五、Version 0模式和re模块不兼容之处

一、安装regex

regex支持Python 2.5+和Python 3.1+,可以用pip命令安装:

pip install regex

PyPy 2.6+也可以使用这个模块。

regex基本兼容re模块,现有的程序可以很容易切换到regex模块:

import regex as re
二、一些有趣的特性

完整的Unicode支持

1,支持最新的Unicode标准,这一点经常比Python本身还及时。

2,支持Unicode代码属性,包括scripts和blocks。

如:\p{Cyrillic}表示西里尔字符(scripts),\p{InCyrillic}表示西里尔区块(blocks)。

3,支持完整的Unicode字符大小写匹配,详见此文

如:ss可匹配ß;cliff(这里的ff是一个字符)可匹配CLIFF(FF是两个字符)。

不需要的话可以关闭此特性。不支持Unicode组合字符与单一字符的大小写匹配,所以感觉这个特性不太实用。

4,regex.WORD标志开启后:

作用1:\b、\B采用Unicode的分界规则,详见此文

如:开启后\b.+?\b可搜索到3.4;关闭后小数点.成为分界符,于是只能搜到['3', '.', '4']。

作用2:采用Unicode的换行符。除了传统的\r、\n,Unicode还有一些换行符,开启后作用于.MULTILINE和.DOTALL模式。

5,\X匹配Unicode的单个字形(grapheme)。

Unicode有时用多个字符组合在一起表示一个字形,详见此文

\X匹配一个字形,如:^\X$可以匹配'\u0041\u0308'。

单词起始位置、单词结束位置

\b是单词分界位置,但不能区分是起始还是结束位置。

regex用\m表示单词起始位置,用\M表示单词结束位置。

(?|...|...)
重置分支匹配中的捕获组编号。

regex.match(r'(?|(first)|(second))', 'first').groups()
('first',)
regex.match(r'(?|(first)|(second))', 'second').groups()
('second',)

两次匹配都是把捕获到的内容放到编号为1捕获组中,在某些情况很方便。

(?flags-flags:...)

局部范围的flag控制。在re模块,flag只能作用于整个表达式,现在可以作用于局部范围了:

 regex.search(r' B (?i:good) /B ', ' B GOOD /B ')
regex.Match object; span=(0, 11), match=' B GOOD /B '

在这个例子里,忽略大小写模式只作用于标签之间的单词。

(?i:)是打开忽略大小写,(?-i:)则是关闭忽略大小写。

如果有多个flag挨着写既可,如(?is-f:),减号左边的是打开,减号右边的是关闭。

除了局部范围的flag,还有全局范围的flag控制,如 (?si-f) B good /B

re模块也支持这个,可以参见Python文档。

把flags写进表达式、而不是以函数参数的方式声明,方便直观且不易出错。

(?(DEFINE)...)

定义可重复使用的子句

regex.search(r'(?(DEFINE)(?P quant \d+)(?P item \w+))(? quant) (? item)', '5 elephants')
regex.Match object; span=(0, 11), match='5 elephants'

此例中,定义之后,(? quant)表示\d+,(? item)表示\w+。如果子句很复杂,能省不少事。

partial matches

部分匹配。可用于验证用户输入,当输入不合法字符时,立刻给出提示。

可以pickle编译后的正则表达式对象

如果正则表达式很复杂或数量很多,编译需要较长时间。

这时可以把编译好的正则式用pickle存储到文件里,下次使用直接pickle.load()就不必再次编译了。

除了以上这些,还有很多新特性(匹配控制、便利方法等等),这里就不介绍了,请自行查阅文档。

三、模糊匹配

regex有模糊匹配(fuzzy matching)功能,能针对字符进行模糊匹配,提供了3种模糊匹配:

i,模糊插入 d,模糊删除 s,模糊替换

以及e,包括以上三种模糊

举个例子:

 regex.findall('(?:hello){s =2}', 'hallo')
['hallo']

(?:hello){s =2}的意思是:匹配hello,其中最多容许有两个字符的错误。

于是可以成功匹配hallo。

这里只简单介绍一下模糊匹配,详情还是参见文档吧。

四、两种工作模式

regex有Version 0和Version 1两个工作模式,其中的Version 0基本兼容现有的re模块,以下是区别:


只支持简单的字符组。 字符组里可以有嵌套的集合,也可以做集合运算(并集、交集、差集、对称差集)。

默认支持普通的Unicode字符大小写,如Й可匹配й。

这与Python3里re模块的默认行为相同。


默认支持完整的Unicode字符大小写,如ss可匹配ß。

可惜不支持Unicode组合字符与单一字符的大小写匹配,所以感觉这个特性不太实用。可以在表达式里写上(?-f)关闭此特性。


如果什么设置都不做,会采用regex.DEFAULT_VERSION指定的模式。在目前,regex.DEFAULT_VERSION的默认值是regex.V0。

如果想默认使用V1模式,这样就可以了:

import regex
regex.DEFAULT_VERSION = regex.V1

V1模式默认开启.FULLCASE(完整的忽略大小写匹配)。通常用不上这个,所以在忽略大小写匹配时用(?-f)关闭.FULLCASE即可,这样速度更快一点,例如:(?i-f)tag

其中零宽匹配的替换操作差异比如明显。绝大多数正则引擎采用的是Perl流派的作法,于是Version 1也朝着Perl的方向改过去了。

 # Version 0 behaviour (like re)
regex.sub('(?V0).*', 'x', 'test')
'x'
regex.sub('(?V0).*?', '|', 'test')
'|t|e|s|t|'  # Version 1 behaviour (like Perl)
regex.sub('(?V1).*', 'x', 'test')
'xx'
regex.sub('(?V1).*?', '|', 'test')
'|||||||||'

re模块对零宽匹配的实现可能是有误的(见issue1647489);

而V0零宽匹配的搜索和替换会出现不一致的行为(搜索采用V1的方式,替换采用re模块的方式);

在Python 3.7+环境下,re和regex模块的行为同时做了改变,据称是采用了“正确”的方式处理零宽匹配:总是返回第一个匹配(字符串或零宽),但是如果是零宽并且之前匹配的还是零宽则忽略。这和3.6-的re模块、regex的V0模式、V1模式都略有不同。

说着挺吓人的,在实际使用中3.6- re、3.7+ re、V0、V1之间极少出现不兼容的现象。

五、Version 0模式和re模块不兼容之处

上面说了“Version 0基本兼容re模块”,说说不兼容的地方:

1、对零宽匹配的处理。

regex修复了re模块的搜索bug(见issue1647489),但是也带来了不兼容的问题。

在re中,用'.*?'搜索'test'返回:['', '', '', '', ''],也就是:最前、字母之间的3个位置、最后,总共5个位置。

在regex中,则返回:['', 't', '', 'e', '', 's', '', 't', '']

在实际使用中,这个问题几乎不会造成不兼容的情况,所以基本可以忽略此差异。

2、\s的范围。

在re中,\s在这一带的范围是0x09 ~ 0x0D,0x1C ~ 0x1E。

在regex中,\s采用的是Unicode 6.3+标准的\p{Whitespace},在这一带的范围有所缩小,只有:0x09 ~ 0x0D。


python中re模块的使用(正则表达式)

一.什么是正则表达式? 正则表达式,又称规则表达式,通常被用来检索.替换那些符合某个模式(规则)的文本. 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合, ...

Python基础之模块:4、正则表达式和re模块

目录 一.正则表达式 1.正则表达式前戏 2.字符组 3.特殊符号 4.量词 5.贪婪匹配与非贪婪匹配 6.转义符 7.正则表达式实战 二.re模块 1.模块导入 2.常见操作方法 1.findall ...

正则表达式与python中re模块

一个网站,正则表达式入门的,很好 http://www.jb51.net/tools/zhengze.html 下面这个包含对python中re的介绍,也是很不错的http://www.w3cscho ...

Python学习笔记(三十一)正则表达式

---恢复内容开始--- 摘抄自:/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 ...

python的库有多少个?python有多少个模块?

这里列举了大概500个左右的库: !   Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主 ...

使用Python的PIL模块来进行图片对比

使用Python的PIL模块来进行图片对比 在使用google或者baidu搜图的时候会发现有一个图片颜色选项,感觉非常有意思,有人可能会想这肯定是人为的去划分的,呵呵,有这种可能,但是估计人会累死, ...

python全栈开发之正则表达式和python的re模块

正则表达式和python的re模块 python全栈开发,正则表达式,re模块 一 正则表达式 正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的 ...

Excel催化剂开源第24波-较VBA更强大的.Net环境的正则表达式

在VBA上可以调用正则表达式库,从而编写正则表达式自定义函数,这个相信不少VBA开发者已经熟知,但VBA的VBScript正则表达式库毕竟是一个过时的产品,不像.Net那样是与时俱进的,所以两者实现出 ...

Python模块之常用模块,反射以及正则表达式

常用模块  1. OS模块 用于提供系统级别的操作,系统目录,文件,路径,环境变量等 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir('di ...


从原理上理解NodeJS的适用场景

NodeJS是近年来比较火的服务端JS平台,这一方面得益于其在后端处理高并发的卓越性能,另一方面在nodeJS平台上的npm.grunt.express等强大的代码与项目管理应用崛起,几乎重新定义了前 ...

static代码块与{}代码块的比较

第一个例子: public class StaticDemo { { System.out.println('{} 代码块'); } static{ System.out.prin ...

Design pattern---观察者模式

观察者模式:发布/订阅模式,当某对象(被观察者)状态发生改变时所有订阅该对象的观察者对象(观察者)都将更新自己 成员(4种): 1.抽象被观察者:将所有的观察者对象的引用存入一个集合,并且定义了添加 ...

hdu ----3695 Computer Virus on Planet Pandora (ac自动机)

Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 256000/1280 ...

LG1268树的重量

#include bits/stdc++.h using namespace std; #define N 35 #define INF 1e9 int dis[N][N],n,len, ...

bzoj 3170: [Tjoi 2013]松鼠聚会

#include cstdio #include iostream #include algorithm #define M 100008 using nam ...

HDU 2955 01背包(思维)

Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...

WinRT知识积累1之读xml数据

前述:这个知识是在Windows8.1或WP8.1中运用Linq to xml获取一个xml文件里的数据.(网上也很多类似的知识,可以借鉴参考) 平台:windows8.1 metro 或者WP8.1 ...

JavaScript的this用法

1. 全局代码中的this this在全局上下文中,它的值是全局对象本身(Global Object),在浏览器中就是Window  Object,如下图示. 看下面几个例子: //Global sc ...

黑马程序员——OC语言 三大特性之多态

Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) 三大特性之一的多态 (一)多态的基本概念 OC对象具有多态性体现在 Per ...


本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » Python的regex模块——更强大的正则表达式引擎

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情