正则表达式可以包含普通或者特殊字符。绝大部分普通字符,比如 'A'
, 'a'
, 或者 '0'
,都是最简单的正则表达式。它们就匹配自身。你可以拼接普通字符,所以 hello
匹配字符串 'hello'
.
常见的正则表达式的特殊字符如下表格:
特殊字符 | 说明 | 备注 |
---|
.
| 在默认模式下,匹配除换行符以外的任意字符。 如果指定了旗标 DOTALL ,它将匹配包括换行符在内的任意字符。 (?s:.) 将匹配任意字符而无视相关旗标。 | |
/d
| 匹配任何十进制数字,等价于字符类 [0-9] 。 | |
/D
| 匹配任何非数字字符,等价于字符类 [^0-9] 。 | |
/s
| 匹配任何空白字符,等价于字符类 [ \t\n\r\f\v] 。 | |
/S
| 匹配任何非空白字符,等价于字符类 [^ \t\n\r\f\v] 。 | |
/w
| 匹配任何字母与数字字符,等价于字符类 [a-zA-Z0-9_] 。 | |
/W
| 匹配任何非字母与数字字符,等价于字符类 [^a-zA-Z0-9_] 。 | |
^
| 匹配字符串的开头, 并且在 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' 。 | |
*? +? ??
| '*' , '+' 和 '?' 数量限定符都是 贪婪的;它们会匹配尽可能多的文本。 有时这种行为并不被需要;如果 RE <.*> 针对 '<a> b <c>' 进行匹配,它将匹配整个字符串,而不只是 '<a>' 。 在数量限定符之后添加 ? 将使其以 非贪婪 或 最小 风格来执行匹配;也就是将匹配数量尽可能 少的 字符。 使用 RE <.*?> 将只匹配 '<a>' 。
| |
*+ ++
?+
| 类似于 '*' , '+' 和 '?' 数量限定符,添加了 '+' 的形式也将匹配尽可能多的次数。 但是,不同于真正的贪婪型数量限定符,这些形式在之后的表达式匹配失败时不允许反向追溯。 这些形式被称为 占有型 数量限定符。 例如,a*a 将匹配 'aaaa' 因为 a* 将匹配所有的 4 个 'a' ,但是,当遇到最后一个 'a' 时,表达式将执行反向追溯以便最终 a* 最后变为匹配总计 3 个 'a' ,而第四个 'a' 将由最后一个 'a' 来匹配。 然而,当使用 a*+a 时如果要匹配 'aaaa' ,a*+ 将匹配所有的 4 个 'a' ,但是在最后一个 'a' 无法找到更多字符来匹配时,表达式将无法被反向追溯并将因此匹配失败。 x*+ , x++ 和 x?+ 分别等价于 (?>x*) , (?>x+) 和 (?>x?) 。 | python3.11+ |
{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}?
| 将导致结果 RE 匹配之前 RE 的 m 至 n 次重复,尝试匹配尽可能 少的 重复次数。 这是之前数量限定符的非贪婪版本。 例如,在 6 个字符的字符串 'aaaaaa' 上,a{3,5} 将匹配 5 个 'a' 字符,而 a{3,5}? 将只匹配 3 个字符。 | |
{m,n}+
| 将导致结果 RE 匹配之前 RE 的 m 至 n 次重复,尝试匹配尽可能多的重复而 不会 建立任何反向追溯点。 这是上述数量限定符的占有型版本。 例如,在 6 个字符的字符串 'aaaaaa' 上,a{3,5}+aa 将尝试匹配 5 个 'a' 字符,然后,要求再有 2 个 'a' ,这将需要比可用的更多的字符因而会失败,而 a{3,5}aa 的匹配将使 a{3,5} 先捕获 5 个,然后通过反向追溯再匹配 4 个 'a' ,然后用模式中最后的 aa 来匹配最后的 2 个 'a' 。 x{m,n}+ 就等同于 (?>x{m,n}) 。 | python3.11+ |
\
| 转义特殊字符(允许你匹配 '*' , '?' , 或者此类其他),或者表示一个特殊序列;特殊序列之后进行讨论。 | |
[ ]
| 用于表示一个字符集合。在一个集合中: 可以表示字符范围,通过用 '-' 将两个字符连起来。比如 [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 ,包含以下几种情况,集合由 '[' 开始,或者包含下列字符序列 '--' , '&&' , '~~' , 和 '||' 。为了避免警告,需要将它们用反斜杠转义。
| |
|
| A|B , A 和 B 可以是任意正则表达式,创建一个正则表达式,匹配 A 或者 B. 任意个正则表达式可以用 '|' 连接。它也可以在组合(见下列)内使用。扫描目标字符串时, '|' 分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦 A 匹配成功, B 就不再进行匹配,即便它能产生一个更好的匹配。或者说,'|' 操作符绝不贪婪。 如果要匹配 '|' 字符,使用 \| , 或者把它包含在字符集里,比如 [|] .
| |
(...)
| (组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number 转义序列进行再次匹配,之后进行详细说明。要匹配字符 '(' 或者 ')' , 用 \( 或 \) , 或者把它们包含在字符集合里: [(] , [)] . | |
(?…)
| 这是个扩展标记法 (一个 '?' 跟随 '(' 并无含义)。 '?' 后面的第一个字符决定了这个构建采用什么样的语法。这种扩展通常并不创建新的组合; (?P<name>...) 是唯一的例外。 以下是目前支持的扩展。 | |
参考:
https://docs.python.org/3.12/library/re.html#