re
--- 正则表达式操作
源代码: Lib/re.py
这个模块提供了与 Perl 语言类似的正则表达式匹配操作。
模式和被搜索的字符串既可以是 Unicode 字符串 (str
) ,也可以是8位字节串 (bytes
)。 但是,Unicode 字符串与8位字节串不能混用:也就是说,你不能用一个字节串模式去匹配 Unicode 字符串,反之亦然;类似地,当进行替换操作时,替换字符串的类型也必须与所用的模式和搜索字符串的类型一致。
正则表达式使用反斜杠字符 ('\'
) 来表示特殊形式或是允许在使用特殊字符时不引发它们的特殊含义。 这会与 Python 的字符串字面值中对相同字符出于相同目的的用法产生冲突;例如,要匹配一个反斜杠字面值,用户可能必须写成 '\\\\'
来作为模式字符串,因为正则表达式必须为 \\
,而每个反斜杠在普通 Python 字符串字面值中又必须表示为 \\
。 而且还要注意,在 Python 的字符串字面值中使用的反斜杠如果有任何无效的转义序列,现在将会产生 DeprecationWarning
并将在未来改为 SyntaxError
。 此行为即使对于正则表达式来说有效的转义字符同样会发生。
解决办法是对于正则表达式样式使用 Python 的原始字符串表示法;在带有 'r'
前缀的字符串字面值中,反斜杠不必做任何特殊处理。 因此 r"\n"
表示包含 '\'
和 'n'
两个字符的字符串,而 "\n"
则表示只包含一个换行符的字符串。 样式在 Python 代码中通常都会使用这种原始字符串表示法来表示。
绝大部分正则表达式操作都提供为模块函数和方法,在 编译正则表达式. 这些函数是一个捷径,不需要先编译一个正则对象,但是损失了一些优化参数。
参见
第三方模块 regex , 提供了与标准库 re
模块兼容的API接口, 同时还提供了额外的功能和更全面的Unicode支持。
正则表达式语法
一个正则表达式(或RE)指定了一集与之匹配的字符串;模块内的函数可以让你检查某个字符串是否跟给定的正则表达式匹配(或者一个正则表达式是否匹配到一个字符串,这两种说法含义相同)。
正则表达式可以拼接; 如果 A 和 B 都是正则表达式, 那么 AB 也是正则表达式。 通常, 如果字符串 p 匹配 A 并且另一个字符串 q 匹配 B, 那么 pq 可以匹配 AB。除非 A 或者 B 包含低优先级操作,A 和 B 存在边界条件;或者命名组引用。所以,复杂表达式可以很容易的从这里描述的简单源语表达式构建。 了解更多正则表达式理论和实现,参考the Friedl book [Frie09] ,或者其他编译器构建的书籍。
以下是正则表达式格式的简要说明。更详细的信息和演示,参考 正则表达式HOWTO。
正则表达式可以包含普通或者特殊字符。绝大部分普通字符,比如 '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')'
。
-
不在集合范围内的字符可以通过 取反 来进行匹配。如果集合首字符是
'^'
,所有 不 在集合内的字符将会被匹配,比如[^5]
将匹配所有字符,除了'5'
,[^^]
将匹配所有字符,除了'^'
.^
如果不在集合首位,就没有特殊含义。 -
在集合内要匹配一个字符
']'
,有两种方法,要么就在它之前加上反斜杠,要么就把它放到集合首位。比如,[()[\]{}]
和[]()[{}]
都可以匹配括号。
-
Unicode Technical Standard #18 里的嵌套集合和集合操作支持可能在未来添加。这将会改变语法,所以为了帮助这个改变,一个
FutureWarning
将会在有多义的情况里被raise
,包含以下几种情况,集合由'['
开始,或者包含下列字符序列'--'
,'&&'
,'~~'
, 和'||'
。为了避免警告,需要将它们用反斜杠转义。
在 3.7 版更改: 如果一个字符串构建的语义在未来会改变的话,一个 FutureWarning
会 raise
。
|
A|B
, A 和 B 可以是任意正则表达式,创建一个正则表达式,匹配 A 或者 B. 任意个正则表达式可以用 '|'
连接。它也可以在组合(见下列)内使用。扫描目标字符串时, '|'
分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦 A 匹配成功, B 就不再进行匹配,即便它能产生一个更好的匹配。或者说,'|'
操作符绝不贪婪。 如果要匹配 '|'
字符,使用 \|
, 或者把它包含在字符集里,比如 [|]
.
(...)
(组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number
转义序列进行再次匹配,之后进行详细说明。要匹配字符 '('
或者 ')'
, 用 \(
或 \)
, 或者把它们包含在字符集合里: [(]
, [)]
.
(?…)
这是个扩展标记法 (一个 '?'
跟随 '('
并无含义)。 '?'
后面的第一个字符决定了这个构建采用什么样的语法。这种扩展通常并不创建新的组合; (?P<name>...)
是唯一的例外。 以下是目前支持的扩展。
(?aiLmsux)
( 'a'
, 'i'
, 'L'
, 'm'
, 's'
, 'u'
, 'x'
中的一个或多个) 这个组合匹配一个空字符串;这些字符对正则表达式设置以下标记 re.A
(只匹配ASCII字符), re.I
(忽略大小写), re.L
(语言依赖), re.M
(多行模式), re.S
(点dot匹配全部字符), re.U
(Unicode匹配), and re.X
(冗长模式)。 (这些标记在 模块内容 中描述) 如果你想将这些标记包含在正则表达式中,这个方法就很有用,免去了在 re.compile()
中传递 flag 参数。标记应该在表达式字符串首位表示。
(?:…)
正则括号的非捕获版本。 匹配在括号内的任何正则表达式,但该分组所匹配的子字符串 不能 在执行匹配后被获取或是之后在模式中被引用。
(?aiLmsux-imsx:…)
('a'
, 'i'
, 'L'
, 'm'
, 's'
, 'u'
, 'x'
中的0或者多个, 之后可选跟随 '-'
在后面跟随 'i'
, 'm'
, 's'
, 'x'
中的一到多个 .) 这些字符为表达式的其中一部分 设置 或者 去除 相应标记 re.A
(只匹配ASCII), re.I
(忽略大小写), re.L
(语言依赖), re.M
(多行), re.S
(点匹配所有字符), re.U
(Unicode匹配), and re.X
(冗长模式)。(标记描述在 模块内容 .)
'a'
,