上文介绍的是正则表达式本身的语法知识,并未涉及实际使用的方法。本文将介绍在Python语言中如何使用正则表达式。
在Python中,通过内置的re模块提供对正则表达式的支持。正则表达式会被编译成一系列的字节码,然后由通过C编写的正则表达式引擎进行执行。该引擎自从Python1.6被内置以来,近20年时间未有发生过变化,实乃我辈楷模。
re模块支持下面的正则语法:
"."
"^"
"$"
"*"
"+"
"?"
*?,+?,??
{m,n}
{m,n}?
"\\"
[]
"|"
(...)
(?aiLmsux)
(?:...)
(?P<name>...)
(?P=name)
(?#...)
(?=...)
(?!...)
(?<=...)
(?<!...)
(?(id/name)yes|no)
支持下面的字符集或转义:
\number
\A
\Z
\b
\B
\d
\D
\s
\S
\w
\W
\\
提供了下面的方法进行字符串的查找、替换和分割等各种处理操作。
方法 | 描述 | 返回值 |
---|---|---|
compile(pattern[, flags]) | 根据包含正则表达式的字符串创建模式对象 | re对象 |
search(pattern,string[,flags]) | 在字符串中查找 | 第一个匹配到的对象或者None |
match(pattern,string[,flags]) | 在字符串的开始处匹配模式 | 在字符串开头匹配到的对象或者None |
split(pattern,string[, maxsplit=0,flags]) | 根据模式的匹配项来分割字符串 | 分割后的字符串列表 |
findall(pattern, string,flags) | 列出字符串中模式的所有匹配项 | 所有匹配到的字符串列表 |
sub(pat,repl,string[,count=0,flags]) | 将字符串中所有的pat的匹配项用repl替换 | 完成替换后的新字符串 |
finditer(pattern,string,flags) | 将所有匹配到的项生成一个迭代器 | 所有匹配到的字符串组合成的迭代器 |
subn(pat,repl,string[,count=0,flags]) | 在替换字符串后,同时报告替换的次数 | 完成替换后的新字符串及替换次数 |
escape(string) | 将字符串中所有特殊正则表达式字符串转义 | 转义后的字符串 |
purge(pattern) | 清空正则表达式 | |
template(pattern[,flags]) | 编译一个匹配模板 | 模式对象 |
fullmatch(pattern,string[, flags]) | match方法的全字符串匹配版本 | 类似match的返回值 |
同时还定义了下面几种匹配模式,单个大写字母是缩写,单词是完整模式名称,引用方法为re.A
或者re.ASCII
,两者都可以,注意全部是大写:
A :ASCII
I :IGNORECASE
L :LOCALE
M :MULTILINE
S :DOTALL
X :VERBOSE
U :UNICODE
反斜杠的困扰:\
与大多数编程语言相同,正则表达式里使用\
作为转义字符,这可能造成反斜杠困扰。假如需要匹配文本中的字符\
,那么使用编程语言表示的正则表达式里将需要4个反斜杠\\\\
。前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。为了方便我们使用个,Python提供了原生字符串的功能,很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"
表示。同样,匹配一个数字的"\\d"
可以直接写成r"\d"
。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
一、compile(pattern, flags=0)
这个方法是re模块的工厂方法,用于将字符串形式的正则表达式编译为Pattern模式对象,可以实现更高效率的匹配。第二个参数flag是匹配模式。
使用compile()
完成一次转换后,再次使用该匹配模式的时候就不用进行转换了。经过compile()
转换的正则表达式对象也能使用普通的re方法。其用法如下:
>>> import re
>>> pat = re.compile(r"abc")
>>> pat.match("abc123")
<_sre.SRE_Match object; span=(0, 3), match='abc'>
>>> pat.match("abc123").group
<built-in method group of _sre.SRE_Match object at 0x00000000035104A8>
>>> pat.match("abc123").group()
'abc'
经过compile()方法编译过后的返回值是个re对象,它可以调用match()、search()、findall()等其他方法,但其他方法不能调用compile()方法。实际上,match()和search()等方法在使用前,Python内部帮你进行了compile的步骤。
>>> re.match(r"abc","abc123").compile()
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
re.match(r"abc","abc123").compile()
AttributeError: '_sre.SRE_Match' object has no attribute 'compile'
那么是使用compile()还是直接使用re.match()
呢?看场景!如果你只是简单的匹配一下后就不用了,那么re.match()
这种简便的调用方式无疑来得更简单快捷。如果你有个模式需要进行大量次数的匹配,那么先compile编译一下再匹配的方式,效