上篇「正则表达式入门」我们讲到元字符. ^ $ * + ? { } [ ] \ | ( )
,以及各种结构:字符组、多选结构、反向引用等等,但没有涉及代码实操。
为了让广大Python爱好者使用正则表达式时得心应手,今天鸽婆奉上re模块的知识集锦!全文框架如下:
Python的re模块
不同于Perl等语言,Python自身并不支持正则表达式,但我们可以通过强大的内置模块re实现,只需要import re
即可。
Python的re模块由两个对象组成:RegexObject和MatchObject。
RegexObject又称为模式对象(pattern object),表示已编译的正则表达式,可以理解为匹配方式;MatchObject是匹配对象,可以理解为匹配结果。
pattern = re.compile(r'<HTML>') # RegexObject模式对象
pattern.match("<HTML><head>") # MatchObject匹配对象
# 输出:<re.Match object; span=(0, 6), match='<HTML>'>
上面的pattern是编译好的RegexObject模式对象,pattern.match()是MatchObject匹配对象。注意Python在字符串文本前面加上“r”表示原始字符串(raw string),这样反斜杠\
会被视为文本字符而不是转义符。除了正则表达式,我们在提供文件路径时也会用到“r”。
RegexObject
匹配操作
要使用这个编译好的正则表达式匹配文本,我们可以对RegexObject进行如下操作:
匹配操作 | 功能 |
---|---|
match() | 从字符串的开头匹配,找到第一个匹配项返回MatchObject。 |
search() | 在字符串的任意位置匹配,找到第一个匹配项返回MatchObject。 |
findall() | 找到匹配的所有子字符串,返回一个列表。 |
finditer() | 找到匹配的所有子字符串,返回一个MatchObject迭代器。 |
需要注意的是,findall()操作返回的是所有不重叠的匹配项,包括空字符串。
pattern = re.compile(r'a*')
pattern.findall("aba")
# 输出:['a', '', 'a', '']
修改操作
我们也可以用RegexObject实现分割和替换等操作,来修改原字符串:
修改操作 | 功能 |
---|---|
split() | 根据匹配的地方,将字符串拆分为一个列表 |
sub() | 用指定字符串替换所有匹配的子字符串,返回新字符串 |
subn() | 与 sub() 相同,但返回新字符串和替换次数 |
一个实用的案例是用代表任何非字母数字字符序列的分隔符来切分句子:
pattern = re.compile(r'\W+')
pattern.split('This is a test of split().')
# 输出:['This', 'is', 'a', 'test', 'of', 'split', '']
MatchObject
re模块的第二个组成部分是MatchObject。
前面我们看到,匹配操作通常返回匹配对象MatchObject(除了findall()
返回的是列表),包含匹配内容和匹配位置等属性。我们可以通过下列方法获取这些信息:
方法 | 功能 |
---|---|
group() | 返回匹配的字符串 |
start() | 返回匹配的开始位置 |
end() | 返回匹配的结束位置 |
span() | 返回包含匹配(start, end) 位置的元组 |
下面是获取匹配内容的示例:
pattern = re.compile(r'<HTML>')
pattern.match("<HTML><head>").group()
# 输出:'<HTML>'
最后说明一下,以上代码都是用re.compile()
先编译正则表达式,返回编译好的RegexObject对象。编译过程将正则模式转换为字节码(bytecode),方便C语言编写的匹配引擎执行,并且缓存正则表达式以重复利用。
但是,我们也可以隐式调用compile(),即直接使用re模块中的函数,避开创建RegexObject对象的步骤,这样更快捷。
简单来说,就是下面两种操作是等同的:
pattern = re.compile(r'<HTML>')
pattern.match("<HTML><head>")
# 输出:<re.Match object; span=(0, 6), match='<HTML>'>
<==>
re.match(r'<HTML>', "<HTML><head>")
# 输出:<re.Match object; span=(0, 6), match='<HTML>'>
re模块整理完毕~
下篇「正则表达式进阶」不见不散~