正则表达式
正则表达式(称为RE,或正则,或正则表达式模式)本质上是嵌入在Python中的一种微小的、高度专业化的编程语言,Python通过标准库中的re
模块来支持正则表达式。使用这种小语言,你可以为要匹配的可能字符串集指定规则;此集可能包含url,电子邮件地址,电话号码或你喜欢的任何内容。
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
1 元字符与特殊字符
1.1 元字符
大多数字符只会匹配自己。 例如,正则表达式 test
将完全匹配字符串 test
;当然,你也可以启用一个不区分大小写(re.I
)的模式,让这个正则匹配 Test
或 TEST
。
>>> re.search('test','RE test')
<re.Match object; span=(3, 7), match='test'>
>>> re.search('test','RE Test')
>>> re.search('test','RE Test',re.I)
<re.Match object; span=(3, 7), match='Test'>
>>>
另一些字符是特殊的元字符,它们不匹配自己——它们表示应该匹配一些与众不同的东西,或者通过重复它们或改变它们的含义来影响正则的其他部分。
完整的元字符列表如下:
. ^ $ * + ? { } [ ] \ | ( )
模式 | 描述 |
---|---|
. |
匹配除\n 之外的任何字符 |
^ |
匹配字符串起始部分 |
$ |
匹配字符串终止部分 |
* |
匹配0次或多次前面出现的正则表达式 |
+ |
匹配1次或多次前面出现的正则表达式 |
? |
匹配0次或1次前面出现的正则表达式 |
{N} |
匹配N次前面出现的正则表达式 |
{N, } |
匹配至少N次前面出现的正则表达式 |
{N, M} |
匹配N-M次前面出现的正则表达式 |
[...] |
匹配来自字符集的任意单一字符 |
[^...] |
不匹配此字符集中出现的任意一个字符 |
() |
匹配括号内的表达式,也表示一个组 |
A|B |
A和B可以是任意正则表达式,创建一个正则表达式,匹配 A或者B |
\ |
转义特殊字符 |
(1)[]
元字符
-
[aeiou]
将匹配a
、e
、i
、o
或u
任意一个字符; -
[]
中可以使用-
表示字符范围,如[0-9]
, 表示匹配0-9中的任意一个数字;同理[a-z]
或[A-F]
; -
[]
字符集中的元字符不生效,如[$]
,表示匹配$
字符;虽然$
是元字符,但在[]
中$
没有特殊性; -
[^aeiou]
表示不匹配任何a
、e
、i
、o
或u
字符;>>> re.match('[aeiou]','abc') <re.Match object; span=(0, 1), match='a'> >>> re.match('[^aeiou]','abc') >>>
-
[^^]
表示匹配任何字符(字符^
除外);>>> re.match('[^^]*','abc^abc') <re.Match object; span=(0, 3), match='abc'>
-
^
如果不放在[]
首位,则没有特殊含义。
(2)*
元字符
-
*
指定前一个字符匹配0次或多次; -
*
元字符的重复默认是贪婪(尽可能匹配多个字符)的,如w.*w
,字符串ww
将匹配ww
,而字符串wowoooow
将匹配wowoooow
; -
取消
*
号贪婪模式很简单,只需要在后面加?
元字符。如w.*?w
,字符串wowoooow
将匹配wow
。>>> re.match('w.*w','ww') <re.Match object; span=(0, 2), match='ww'> >>> re.match('w.*w','wowoooow') <re.Match object; span=(0, 8), match='wowoooow'> >>> re.match('w.*?w','wowoooow') <re.Match object; span=(0, 3), match='wow'>
注:
-
+
与*
类似,只不过+
是匹配前一个正则(或前一个字符)1次或多次。 -
?
指定匹配前一个正则(或前一个字符)0次或1次;或者你可以想象前一个正则(前一个字符)是可选的:good-?job
正则将匹配goodjob
或good-job
。>>> re.match('good-?job','goodjob') <re.Match object; span=(0, 7), match='goodjob'> >>> re.match('good-?job','good-job') <re.Match object; span=(0, 8), match='good-job'>
(3){}
元字符
{}
元字符与+
、*
、?
类似,也是用于正则重复(多次匹配)的。{N, M}
表示最少匹配N次,最多匹配M次;{N}
表示匹配N次,少于N次将匹配失败。
{0,1}
等价于?
;{0,}
等价于*
;{1,}
等价于+
;
(4)\
元字符
Python字符串使用"\"
转译字符,而反斜杠要表示其本身时需要使用"\\"
;正则表达式也使用\
元字符将普通字符转移为特殊字符(见表1-2)或允许使用特殊字符(如\.
代表匹配字符点号本身,不代表元字符.
)而不调用它们的特殊含义,同理,表示其本身时也是使用\\
。
当正则表达式需要匹配反斜杠时,正则表达式必须为\\
,但因为使用的是Python字符串表示正则字符串,Python字符串"\\"
被当作一个反斜杠,所以要使用正则字符串\\
,必须使用Python字符串"\\\\"
表示正则字符串\\
。
>>> re.match('\\\\','\\123')
<re.Match object; span=(0, 1), match='\\'>
>>> re.match('\\','\\123')
Traceback (most recent call last):
...
re.error: bad escape (end of pattern) at position 0
反复使用反斜杠的正则表达式,会导致大量重复的反斜杠,并使得正则字符串难以理解。解决办法是——使用Python的原始字符串表示法来表示正则表达式。
原始字符串是加了前缀r
的字符串,在原始字符串中反斜杠不再特殊。如字符串r"\n"
是一个包含 '\'
和 'n'
的双字符字符串,而 "\n"
是一个包含换行符的单字符字符串。
>>> re.match