Python 正则表达式
语法
在线工具:正则表达式可视化工具与正则表达式在线测试工具
特殊字符
-
.
(点) 在默认模式,匹配除了换行的任意字符。如果指定了标签
re.DOTALL
,它将匹配包括换行符的任意字符。 -
^
(插入符号) 匹配字符串的开头, 并且在
re.MULTILINE
模式也匹配换行后的首个符号。 -
$
匹配字符串尾或者在字符串尾的换行符的前一个字符,在
re.MULTILINE
模式下也会匹配换行符之前的文本。foo
匹配 ‘foo’ 和 ‘foobar’,但正则表达式foo$
只匹配 ‘foo’。- 更有趣的是,在
'foo1\nfoo2\n'
中搜索foo.$
,通常匹配 ‘foo2’,但在re.MULTILINE
模式下可以匹配到 ‘foo1’;在'foo\n'
中搜索$
会找到两个(空的)匹配:一个在换行符之前,一个在字符串的末尾。
- 更有趣的是,在
-
*
对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。
ab*
会匹配'a'
,'ab'
,或者'a'
后面跟随任意个'b'
。相当于{0,}
-
+
对它前面的正则式匹配1到任意次重复。
ab+
会匹配'a'
后面跟随1个以上到任意个'b'
,它不会匹配'a'
。相当于{1,}
-
?
对它前面的正则式匹配0到1次重复。
ab?
会匹配'a'
或者'ab'
。相当于{0,1}
-
*?
,+?
,??
'*'
,'+'
,和'?'
修饰符都是 贪婪的;它们在字符串进行尽可能多的匹配。有时候并不需要这种行为。- 如果正则式
<.*>
希望找到'<a> b <c>'
,它将会匹配整个字符串,而不仅是'<a>'
。在修饰符之后添加?
将使样式以非贪婪方式或者最小方式进行匹配; 尽量少的字符将会被匹配。 使用正则式<.*?>
将会仅仅匹配'<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
,包含以下几种情况,集合由'['
开始,或者包含下列字符序列'--'
,'&&'
,'~~'
, 和'||'
。为了避免警告,需要将它们用反斜杠转义。
-
-
|
A|B
, A 和 B 可以是任意正则表达式,创建一个正则表达式,匹配 A 或者 B. 任意个正则表达式可以用'|'
连接。它也可以在组合(见下列)内使用。扫描目标字符串时,'|'
分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦 A 匹配成功, B 就不再进行匹配,即便它能产生一个更好的匹配。或者说,'|'
操作符绝不贪婪。 如果要匹配'|'
字符,使用\|
, 或者把它包含在字符集里,比如[|]
. -
(...)
(组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用
\number
转义序列进行再次匹配,之后进行详细说明。要匹配字符'('
或者')'
, 用\(
或\)
, 或者把它们包含在字符集合里:[(]
,[)]
. -
(?…)
这是个扩展标记法 (一个
'?'
跟随'('
并无含义)。'?'
后面的第一个字符决定了这个构建采用什么样的语法。这种扩展通常并不创建新的组合;(?P<name>...)
是唯一的例外。 以下是目前支持的扩展。
\ + 字符
由 '\'
和一个字符组成的特殊序列在以下列出。 如果普通字符不是ASCII数位或者ASCII字母,那么正则样式将匹配第二个字符。比如,\$
匹配字符 '$'
.
-
\number
匹配数字代表的组合。每个括号是一个组合,组合从1开始编号。
- 比如
(.+) \1
匹配'the the'
或者'55 55'
, 但不会匹配'thethe'
(注意组合后面的空格)。这个特殊序列只能用于匹配前面99个组合。 - 如果 number 的第一个数位是0, 或者 number 是三个八进制数,它将不会被看作是一个组合,而是八进制的数字值。在
'['
和']'
字符集合内,任何数字转义都被看作是字符。
- 比如
-
\A
只匹配字符串开始。
-
\b
匹配空字符串,但只在单词开始或结尾的位置。一个单词被定义为一个单词字符的序列。
- 注意,通常
\b
定义为\w
和\W
字符之间,或者\w
和字符串开始/结尾的边界, 意思就是r'\bfoo\b'
匹配'foo'
,'foo.'
,'(foo)'
,'bar foo baz'
但不匹配'foobar'
或者'foo3'
。 - 默认情况下,Unicode字母和数字是在Unicode样式中使用的,但是可以用
ASCII
标记来更改。如果LOCALE
标记被设置的话,词的边界是由当前语言区域设置决定的,\b
表示退格字符,以便与Python字符串文本兼容。
- 注意,通常
-
\B
匹配空字符串,但 不 能在词的开头或者结尾。意思就是
r'py\B'
匹配'python'
,'py3'
,'py2'
, 但不匹配'py'
,'py.'
, 或者'py!'
.\B
是\b
的取非,所以Unicode样式的词语是由Unicode字母,数字或下划线构成的,虽然可以用ASCII
标志来改变。如果使用了LOCALE
标志,则词的边界由当前语言区域设置。 -
\d
对于 Unicode (str) 样式:匹配任何Unicode十进制数(就是在Unicode字符目录[Nd]里的字符)。这包括了
[0-9]
,和很多其他的数字字符。如果设置了ASCII
标志,就只匹配[0-9]
。-对于8位(bytes)样式:匹配任何十进制数,就是
[0-9]
。 -
\D
匹配任何非十进制数字的字符。就是
\d
取非。 如果设置了ASCII
标志,就相当于[^0-9]
。 -
\s
-
对于 Unicode (str) 样式:匹配任何Unicode空白字符(包括
[ \t\n\r\f\v]
,还有很多其他字符,比如不同语言排版规则约定的不换行空格)。如果ASCII
被设置,就只匹配[ \t\n\r\f\v]
。 -
对于8位(bytes)样式:匹配ASCII中的空白字符,就是
[ \t\n\r\f\v]
。
-
-
\S
匹配任何非空白字符。就是
\s
取非。如果设置了ASCII
标志,就相当于[^ \t\n\r\f\v]
。 -
\w
对于 Unicode (str) 样式:匹配Unicode词语的字符,包含了可以构成词语的绝大部分字符,也包括数字和下划线。如果设置了
ASCII
标志,就只匹配[a-zA-Z0-9_]
。对于8位(bytes)样式:匹配ASCII字符中的数字和字母和下划线,就是[a-zA-Z0-9_]
。如果设置了LOCALE
标记,就匹配当前语言区域的数字和字母和下划线。 -
\W
匹配非单词字符的字符。这与
\w
正相反。如果使用了ASCII
旗标,这就等价于[^a-zA-Z0-9_]
。如果使用了LOCALE
旗标,则会匹配当前区域中既非字母数字也非下划线的字符。 -
\Z
只匹配字符串尾。
-
绝大部分Python的标准转义字符也被正则表达式分析器支持。:
\a \b \f \n
\N \r \t \u
\U \v \x \\
Note:
\b
被用于表示词语的边界,它只在字符集合内表示退格,比如[\b]
。
'\u'
,'\U'
和'\N'
转义序列只在 Unicode 模式中可被识别。 在 bytes 模式中它们会导致错误。 未知的 ASCII 字母转义序列保留在未来使用,会被当作错误来处理。八进制转义包含为一个有限形式。如果首位数字是 0, 或者有三个八进制数位,那么就认为它是八进制转义。其他的情况,就看作是组引用。对于字符串文本,八进制转义最多有三个数位长。
元字符
元字符 | 描述 |
---|---|
. |
匹配任意单个字符,除了\n |
[ ] |
字符种类,匹配方括号内任意字符 |
[^ ] |
否定的字符种类,匹配除了方括号里的任意字符 |
* |
匹配0到任意次重复,相当于{0,} |
+ |
匹配1到任意次重复,相当于{1,} |
? |
匹配0到1次重复,相当于{0,1} |
{n, m} |
对正则式进行 m 到 n 次匹配 |
(xyz) |
字符集,匹配与xyz完全相等的字符串 |
| |
或运算,匹配符号前或符号后的字符 |
\ |
转义字符,用于匹配保留字() [] {} . * + ? ^ $ \ | |
^ |
匹配字符串开始的位置 |
$ |
匹配字符串结尾的位置 |
拓展语法
拓展语法
-
(?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匹配), andre.X
(冗长模式)。(标记描述) 'a'
,'L'
and'u'
作为内联标记是相互排斥的, 所以它们不能结合在一起,或者跟随'-'
。 当他们中的某个出现在内联组中,它就覆盖了括号组内的匹配模式。- 在Unicode样式中,
(?a:...)
切换为 只匹配ASCII,(?u:...)
切换为Unicode匹配 (默认). - 在byte样式中
(?L:...)
切换为语言依赖模式,(?a:...)
切换为 只匹配ASCII (默认)。这种方式只覆盖组合内匹配,括号外的匹配模式不受影响。
- 在Unicode样式中,
- 这些字符为表达式的其中一部分 对应一种匹配标志:
-
(?P<name>…)
(命名组合)类似正则组合,但是匹配到的子串组在外部是通过定义的
name
来获取的。组合名必须是有效的Python标识符,并且每个组合名只能用一个正则表达式定义,只能定义一次。一个符号组合同样是一个数字组合,就像这个组合没有被命名一样。命名组合可以在三种上下文中引用。如果样式是(?P<quote>['"]).*?(?P=quote)
(也就是说,匹配单引号或者双引号括起来的字符串):引用组合 “quote” 的上下文 引用方法 在正则式自身内 (?P=quote) (如示),\1
处理匹配对象 m m.group('quote'),m.end('quote')
(等)传递到 re.sub()
里的 repl 参数中\g<quote>,\g<1>,\1
-
(?P=name)
反向引用一个命名组合;它匹配前面那个叫 name 的命名组中匹配到的串同样的字串。
-
(?#…)
注释;里面的内容会被忽略。
-
(?=…)
匹配
…
的内容,但是并不消费样式的内容。这个叫做 lookahead a