Zwlin's Blog

Python正则表达式

2020/02/01

概述

正则表达式(称为RE,或正则,或正则表达式模式)本质上是嵌入在 Python 中的一种微小的、高度专业化的编程语言,可通过re模块获得。 使用这种小语言,你可以为要匹配的可能字符串集指定规则;此集可能包含英语句子,电子邮件地址,TeX命令或你喜欢的任何内容。 然后,您可以询问诸如“此字符串是否与模式匹配?”或“此字符串中的模式是否匹配?”等问题。 你还可以使用正则修改字符串或以各种方式将其拆分。

正则表达式模式被编译成一系列字节码,然后由用 C 编写的匹配引擎执行。对于高级用途,可能需要特别注意引擎如何执行给定的正则,并将正则写入以某种方式生成运行速度更快的字节码。 本文档未涉及优化,因为它要求你充分了解匹配引擎的内部结构。

正则表达式语言相对较小且受限制,因此并非所有可能的字符串处理任务都可以使用正则表达式完成。 还有一些任务 可以 用正则表达式完成,但表达式变得非常复杂。 在这些情况下,你最好编写 Python 代码来进行处理;虽然 Python 代码比精心设计的正则表达式慢,但它也可能更容易理解。

常用正则表达式语法

正则表达式可以包含普通或者特殊字符。绝大部分普通字符,比如A, a, 或者 0,都是最简单的正则表达式。它们就匹配自身。你可以拼接普通字符,所以 last 匹配字符串 ’last'.

有些字符,比如 | 或者 (,属于特殊字符。 特殊字符既可以表示它的普通含义, 也可以影响它旁边的正则表达式的解释。

重复修饰符 *, +, ?, {m,n}, 不能直接嵌套。这样避免了非贪婪后缀 ? 修饰符,和其他实现中的修饰符产生的多义性。要应用一个内层重复嵌套,可以使用括号。 比如,表达式 (?:a{6})* 匹配6个 ‘a’ 字符重复任意次数。

特殊字符意义
.(点) 在默认模式,匹配除了换行的任意字符。如果指定了标签DOTALL,它将匹配包括换行符的任意字符。
^(插入符号) 匹配字符串的开头, 并且在MULTILINE模式也匹配换行后的首个符号。
$匹配字符串尾或者换行符的前一个字符,在 MULTILINE 模式匹配换行符的前一个字符。
*对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。
+对它前面的正则式匹配1到任意次重复。
?对它前面的正则式匹配0到1次重复。
*?,+?,??非贪婪方式的*,+,?
[m]对其之前的正则式指定匹配 m 个重复;少于 m 的话就会导致匹配失败。
[m,n]对正则式进行 m 到 n 次匹配,在 m 和 n 之间取尽量多。
[m,n?][m,n]的非贪婪模式,只匹配尽量少的字符次数。
\转义特殊字符(允许你匹配 ‘*’, ‘?’, 或者此类其他),或者表示一个特殊序列。
[]用于表示一个字符集合。
``
(...)(组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number 转义序列进行再次匹配
(?...)这是个扩展标记法 (一个 ‘?’ 跟随 ‘(’ 并无含义)。 ‘?’ 后面的第一个字符决定了这个构建采用什么样的语法。
(?:...)正则括号的非捕获版本。 匹配在括号内的任何正则表达式,但该分组所匹配的子字符串不能在执行匹配后被获取或是之后在模式中被引用。
(?P<name>…)(命名组合)类似正则组合,但是匹配到的子串组在外部是通过定义的 name 来获取的。
(?P=name)反向引用一个命名组合;它匹配前面那个叫 name 的命名组中匹配到的串同样的字串。
(?=…)匹配 … 的内容,但是并不消费样式的内容。比如, Isaac (?=Asimov) 匹配 ‘Isaac ’ 只有在后面是 ‘Asimov’ 的时候
(?!…)匹配 … 不符合的情况。比如说, Isaac (?!Asimov) 只有后面 不 是 ‘Asimov’ 的时候才匹配 ‘Isaac ’ 。
\number匹配数字代表的组合。每个括号是一个组合,组合从1开始编号。
\A只匹配字符串开始。
\b匹配空字符串,但只在单词开始或结尾的位置。一个单词被定义为一个单词字符的序列。
\B匹配空字符串,但能在词的开头或者结尾。
\d匹配数字
\D匹配任何非十进制数字的字符。就是 \d 取非。 如果设置了 ASCII 标志,就相当于 [^0-9] 。
\s匹配任何Unicode空白字符。
\S匹配任何非空白字符。就是 \s 取非。如果设置了 ASCII 标志,就相当于 [^ \t\n\r\f\v] 。
\w匹配Unicode词语的字符,包含了可以构成词语的绝大部分字符。
\W匹配任何不是单词字符的字符。
\Z只匹配字符串尾。

更多用法参考文档

re — 正则表达式操作