Python正则式的基本用法
1.1基本规则
1.2重复
1.2.1最小匹配与精确匹配
1.3前向界定与后向界定
1.4组的基本知识
2.re模块的基本函数
2.1使用compile加速
2.2 match和search
2.3 finditer
2.4字符串的修改与替换
3.更深入的了解re的组与对象
3.1编译后的Pattern对象
3.2组与Match对象
3.2.1组的名字与序号
3.2.2Match对象的方法
4.更多的资料
初学Python,对Python的文字处理能力有很深的印象,除了str对象自带的一些方法外,就是正则表达式这个强大的模块了。但是对于初学者来说,要用好这个功能还是有点难度,我花了好长时间才摸出了点门道。由于我记性不好,很容易就忘事,所以还是写下来比较好一些,同时也可以加深印象,整理思路。
由于我是初学,所以肯定会有些错误,还望高手不吝赐教,指出我的错误。
1 Python正则式的基本用法
Python的正则表达式的模块是‘re’,它的基本语法规则就是指定一个字符序列,比如你要在一个字符串s=’123abc456’中查找字符串’abc’,只要这样写:
>>> import re
>>> s='123abc456eabc789'
>>> re.findall(r’abc’,s)
结果就是:
['abc', 'abc']
这里用到的函数”findall(rule , target [,flag] )”是个比较直观的函数,就是在目标字符串中查找符合规则的字符串。第一个参数是规则,第二个参数是目标字符串,后面还可以跟一个规则选项(选项功能将在compile函数的说明中详细说明)。返回结果结果是一个列表,中间存放的是符合规则的字符串。如果没有符合规则的字符串被找到,就返回一个空列表。
为什么要用r’ ..‘字符串(raw字符串)?由于正则式的规则也是由一个字符串定义的,而在正则式中大量使用转义字符’\’,如果不用raw字符串,则在需要写一个’\’的地方,你必须得写成’\\’,那么在要从目标字符串中匹配一个’\’的时候,你就得写上4个’\’成为’\\\\’!这当然很麻烦,也不直观,所以一般都使用r’’来定义规则字符串。当然,某些情况下,可能不用raw字符串比较好。
以上是个最简单的例子。当然实际中这么简单的用法几乎没有意义。为了实现复杂的规则查找,re规定了若干语法规则。它们分为这么几类:
功能字符:‘.’ ‘*’ ‘+’ ‘|’ ‘?’ ‘^’ ‘$’ ‘\’等,它们有特殊的功能含义。特别是’\’字符,它是转义引导符号,跟在它后面的字符一般有特殊的含义。
规则分界符:‘[‘ ‘]’ ‘(’ ‘)’ ‘{‘ ‘}’等,也就是几种括号了。
预定义转义字符集:“\d”“\w” “\s”等等,它们是以字符’\’开头,后面接一个特定字符的形式,用来指示一个预定义好的含义。
其它特殊功能字符:’#’ ‘!’ ‘:’ ‘-‘等,它们只在特定的情况下表示特殊的含义,比如(?# …)就表示一个注释,里面的内容会被忽略。
下面来一个一个的说明这些规则的含义,不过说明的顺序并不是按照上面的顺序来的,而是我认为由浅入深,由基本到复杂的顺序来编排的。同时为了直观,在说明的过程中尽量多举些例子以方便理解。
1.1基本规则
‘[‘‘]’字符集合设定符
首先说明一下字符集合设定的方法。由一对方括号括起来的字符,表明一个字符集合,能够匹配包含在其中的任意一个字符。比如[abc123],表明字符’a’ ‘b’ ‘c’ ‘1’ ‘2’ ‘3’都符合它的要求。可以被匹配。
在’[‘ ‘]’中还可以通过’-‘减号来指定一个字符集合的范围,比如可以用[a-zA-Z]来指定所以英文字母的大小写,因为英文字母是按照从小到大的顺序来排的。你不可以把大小的顺序颠倒了,比如写成[z-a]就不对了。
如果在’[‘ ‘]’里面的开头写一个‘^’号,则表示取非,即在括号里的字符都不匹配。如[^a-zA-Z]表明不匹配所有英文字母。但是如果‘^’不在开头,则它就不再是表示取非,而表示其本身,如[a-z^A-Z]表明匹配所有的英文字母和字符’^’。
‘|’或规则
将两个规则并列起来,以‘|’连接,表示只要满足其中之一就可以匹配。比如
[a-zA-Z]|[0-9]表示满足数字或字母就可以匹配,这个规则等价于[a-zA-Z0-9]
注意:关于’|’要注意两点:
第一,它在’[‘ ‘]’之中不再表示或,而表示他本身的字符。如果要在’[‘ ‘]’外面表示一个’|’字符,必须用反斜杠引导,即’\|’ ;
第二,它的有效范围是它两边的整条规则,比如‘dog|cat’匹配的是‘dog’和’cat’,而不是’g’和’c’。如果想限定它的有效范围,必需使用一个无捕获组‘(?: )’包起来。比如要匹配‘I have a dog’或’I have a cat’,需要写成r’I have a (?:dog|cat)’,而不能写成r’I have a dog|cat’
例
>>> s = ‘I have a dog , I have a cat’
>>> re.findall( r’I have a (?:dog|cat)’ , s )
['I have a dog', 'I have a cat']#正如我们所要的
下面再看看不用无捕获组会是什么后果:
>>> re.findall( r’I have a dog|cat’ , s )
['I have a dog', 'cat']#它将’I have a dog’和’cat’当成两个规则了
至于无捕获组的使用,后面将仔细说明。这里先跳过。
‘.’匹配所有字符
匹配除换行符’\n’外的所有字符。如果使用了’S’选项,匹配包括’\n’的所有字符。
例:
>>> s=’123 \n456 \n789’
>>> findall(r‘.+’,s)
['123', '456', '789']
>>> re.findall(r‘.+’ , s , re.S)
['123\n456\n789']
‘^’和’$’匹配字符串开头和结尾
注意’^’不能在‘[ ]’中,否则含意就发生变化,具体请看上面的’[‘ ‘]’说明。在多行模式下,它们可以匹配每一行的行首和行尾。具体请看后面compile函数说明的’M’选项部分
‘\d’匹配数字
这是一个以’\’开头的转义字符,’\d’表示匹配一个数字,即等价于[0-9]
‘\D’匹配非数字
这个是上面的反集,即匹配一个非数字的字符,等价于[^0-9]。注意它们的大小写。下面我们还将看到Python的正则规则中很多转义字符的大小写形式,代表互补的关系。这样很好记。
‘\w’匹配字母和数字
匹配所有的英文字母和数字,即等价于[a-zA-Z0-9]。
‘\W’匹配非英文字母和数字
即’\w’的补集,等价于[^a-zA-Z0-9]。
‘\s’匹配间隔符
即匹配空格符、制表符、回车符等表示分隔意义的字符,它等价于[ \t\r\n\f\v]。(注意最前面有个空格)
‘\S’匹配非间隔符
即间隔符的补集,等价于[^ \t\r\n\f\v]
‘\A’匹配字符串开头
匹配字符串的开头。它和’^’的区别是,’\A’只匹配整个字符串的开头,即使在’M’模式下,它也不会匹配其它行的很首。
‘\Z’匹配字符串结尾
匹配字符串的结尾。它和’$’的区别是,’\Z’只匹配整个字符串的结尾,即使在’M’模式下,它也不会匹配其它各行的行尾。
例:
>>> s= '12 34\n56 78\n90'
>>> re.findall( r'^\d+' , s , re.M )#匹配位于行首的数字
['12', '56', '90']
>>> re.findall( r’\A\d+’, s , re.M )#匹配位于字符串开头的数字
['12']
>>> re.findall( r'\d+$' , s , re.M )#匹配位于行尾的数字
['34', '78', '90']
>>> re.findall( r’\d+\Z’ , s , re.M )#匹配位于字符串尾的数字
['90']
‘\b’匹配单词边界
它匹配一个单词的边界,比如空格等,不过它是一个