re模块提供了与 Perl 语言类似的正则表达式匹配操作
正则表达式用反斜杠字符 ('\'
) 表示特殊形式,或是允许在使用特殊字符时,不引发它们的特殊含义。 这与 Python 的字符串字面值中对相同字符出于相同目的的用法产生冲突;例如,要匹配一个反斜杠字面值,用户可能必须写成 '\\\\'
来作为模式字符串,因为正则表达式必须为 \\
,而每个反斜杠在普通 Python 字符串字面值中又必须表示为 \\
。 而且还要注意,在 Python 的字符串字面值中使用的反斜杠如果有任何无效的转义序列,现在会触发 DeprecationWarning
,但以后会改为 SyntaxError
。 此行为即使对于正则表达式来说有效的转义字符同样会发生。
正则表达式语法
正则表达式(或 RE)指定了一组与之匹配的字符串;模块内的函数可以检查某个字符串是否与给定的正则表达式匹配(或者正则表达式是否匹配到字符串,这两种说法含义相同)。
正则表达式可以拼接;如果 A 和 B 都是正则表达式,则 AB 也是正则表达式。通常,如果字符串 p 匹配 A,并且另一个字符串 q 匹配 B,那么 pq 可以匹配 AB。除非 A 或者 B 包含低优先级操作,A 和 B 存在边界条件;或者命名组引用。所以,复杂表达式可以很容易的从这里描述的简单源语表达式构建。
正则表达式可以包含普通或者特殊字符。绝大部分普通字符,比如 'A'
, 'a'
, 或者 '0'
,都是最简单的正则表达式。它们就匹配自身。你可以拼接普通字符,所以 last
匹配字符串 'last'
. (在这一节的其他部分,我们将用 this special style
这种方式表示正则表达式,通常不带引号,要匹配的字符串用 'in single quotes'
,单引号形式。)有些字符,比如 '|'
或者 '('
,属于特殊字符。 特殊字符既可以表示它的普通含义, 也可以影响它旁边的正则表达式的解释。重复修饰符 (*
, +
, ?
, {m,n}
, 等) 不能直接嵌套。这样避免了非贪婪后缀 ?
修饰符,和其他实现中的修饰符产生的多义性。要应用一个内层重复嵌套,可以使用括号。 比如,表达式 (?:a{6})*
匹配6个 'a'
字符重复任意次数。
特殊字符有:
.
(点) 在默认模式,匹配除了换行的任意字符。如果指定了标签 DOTALL
,它将匹配包括换行符的任意字符。^
(插入符号) 匹配字符串的开头, 并且在 MULTILINE
模式也匹配换行后的首个符号。$
匹配字符串尾或者在字符串尾的换行符的前一个字符,在 MULTILINE
模式下也会匹配换行符之前的文本。 foo
匹配 'foo' 和 'foobar',但正则表达式 foo$
只匹配 'foo'。 更有趣的是,在 'foo1\nfoo2\n'
中搜索 foo.$
,通常匹配 'foo2',但在 MULTILINE
模式下可以匹配到 'foo1';在 'foo\n'
中搜索 $
会找到两个(空的)匹配:一个在换行符之前,一个在字符串的末尾。*
对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。 ab*
会匹配 'a'
,'ab'
,或者 'a'
后面跟随任意个 'b'
。+
对它前面的正则式匹配1到任意次重复。 ab+
会匹配 'a'
后面跟随1个以上到任意个 'b'
,它不会匹配 'a'
。?
对它前面的正则式匹配0到1次重复。 ab?
会匹配 'a'
或者 'ab'
。*?
, +?
, ??
'*'
, '+'
,和 '?'
修饰符都是 贪婪的;它们在字符串进行尽可能多的匹配。有时候并不需要这种行为。如果正则式 <.*>
希望找到 '<a> b <c>'
,它将会匹配整个字符串,而不仅是 '<a>'
。在修饰符之后添加 ?
将使样式以 非贪婪`方式或者 :dfn:`最小 方式进行匹配; 尽量 少 的字符将会被匹配。 使用正则式 <.*?>
将会仅仅匹配 '<a>'
。{m}
对其之前的正则式指定匹配 m 个重复;少于 m 的话就会导致匹配失败。比如, a{6}
将匹配6个 'a'
, 但是不能是5个。{m,n}
对正则式进行 m 到 n 次匹配,在 m 和 n 之间取尽量多。 比如,a{3,5}
将匹配 3 到 5个 'a'
。忽略 m 意为指定下界为0,忽略 n 指定上界为无限次。 比如 a{4,}b
将匹配 'aaaab'
或者1000个 'a'
尾随一个 'b'
,但不能匹配 'aaab'
。逗号不能省略,否则无法辨别修饰符应该忽略哪个边界。{m,n}?
前一个修饰符的非贪婪模式,只匹配尽量少的字符次数。比如,对于 'aaaaaa'
, a{3,5}
匹配 5个 'a'
,而 a{3,5}?
只匹配3个 'a'
。\
转义特殊字符(允许你匹配 '*'
, '?'
, 或者此类其他),或者表示一个特殊序列;特殊序列之后进行讨论。如果你没有使用原始字符串( r'raw'
)来表达样式,要牢记Python也使用反斜杠作为转义序列;如果转义序列不被Python的分析器识别,反斜杠和字符才能出现在字符串中。如果Python可以识别这个序列,那么反斜杠就应该重复两次。这将导致理解障碍,所以高度推荐,就算是最简单的表达式,也要使用原始字符串。[]
用于表示一个字符集合。在一个集合中:
- 字符可以单独列出,比如 [amk]
匹配 'a'
, 'm'
, 或者 'k'
。 - 可以表示字符范围,通过用 '-'
将两个字符连起来。比如 [a-z]
将匹配任何小写ASCII字符, [0-5][0-9]
将匹配从 00
到 59
的两位数字, [0-9A-Fa-f]
将匹配任何十六进制数位。 如果 -
进行了转义 (比如 [a\-z]
)或者它的位置在首位或者末尾(如 [-a]
或 [a-]
),它就只表示普通字符 '-'
。 - 特殊字符在集合中,失去它的特殊含义。比如 [(+*)]
只会匹配这几个文法字符 '('
, '+'
, '*'
, or ')'
。 - 字符类如 \w
或者 \S
(如下定义) 在集合内可以接受,它们可以匹配的字符由 ASCII 或者 LOCALE 模式决定。 - 不在集合范围内的字符可以通过 取反 来进行匹配。如果集合首字符是 '^'
,所有 不 在集合内的字符将会被匹配,比如 [^5]
将匹配所有字符,除了 '5'
, [^^]
将匹配所有字符,除了 '^'
. ^
如果不在集合首位,就没有特殊含义。 - 在集合内要匹配一个字符 ']'
,有两种方法,要么就在它之前加上反斜杠,要么就把它放到集合首位。比如, [()[\]{}]
和 []()[{}]
都可以匹配括号。 - Unicode Technical Standard #18 里的嵌套集合和集合操作支持可能在未来添加。这将会改变语法,所以为了帮助这个改变,一个 FutureWarning 将会在有多义的情况里被 raise
,包含以下几种情况,集合由 '['
开始,或者包含下列字符序列 '--'
, '&&'
, '~~'
, 和 '||'
。为了避免警告,需要将它们用反斜杠转义。