匹配
一旦你拥有了一个经过编译的,代表正则表达式的对象,他能用来做什么呢?模式对象拥有很多方法以及属性。我们在这里只是列出一些重要的部分,如果你想要一个较全的文档,请参见RE的文档:
Method/Attribute | Purpose |
match() | 判断一个模式是否从开始处匹配一个字符串 |
search() | 遍历整个串,寻找一个模式匹配的位置 |
findall() | 查找所有的RE匹配的子串,并且以列表的形式返回 |
finditer() | 查找所有的RE匹配的子串,以迭代器的形式返回 |
如果没有匹配的话,match() 和 search() 会返回 None。 如果匹配成功的话,会返回一个匹配对象,这个对象包含所有匹配的信息,例如从哪儿开始,在哪儿结束,匹配的子串等等。
为学习正则匹配,我们可以在交互式的命令行中使用re模块。如果你装了 tkinter的话,你可以看看Tools/demo/redemo.py,这是python的一个例子程序。使用这个程序你可以输入模式以及串,然后显示出时候模式跟串是匹配的。redemo.py在调试复杂的RE的时候非常有用。Phil Schwartz’s Kodos 也是一个交互式工具,同样也可以用来开发测试正则表达式。
本文中所有的例子都是基于标准的Python解释器。首先,运行python解释器,引入re模块,编译RE:
>>>
>>> importre
>>> p = re.compile('[a-z]+')
>>> p
<_sre.SRE_Pattern object at 0x...>
现在你可以使用RE [a-z]+去匹配各种字符串。+表示匹配一次或者多次,所以空串不可能被匹配, 在本例中,match()应该要返回 None ,所以我们什么也打印不出来。
>>>
>>> p.match("")
>>> print(p.match(""))
None
我们再试一个可以匹配的字符串。比如 tempo. 在下面的例子中, match() 会返回一个匹配对象,我们可以将其存放在变量中供以后使用。
>>>
>>> m = p.match('tempo')
>>> m
<_sre.SRE_Match object at 0x...>
让我们查询一下这个匹配对象来看看里面包含了哪些信息。匹配对象有很多方法属性,最重要的部分有:
Method/Attribute | Purpose |
group() | 返回模式匹配的字符串 |
start() | 返回匹配的起始位置 |
end() | 返回匹配的结束位置 |
span() | 返回匹配位置的元组 |
我们可以再解释器中试试看:
>>>
>>> m.group()
'tempo'
>>> m.start(), m.end()
(0, 5)
>>> m.span()
(0, 5)
group() 返回了RE匹配的子串. start() 和 end() 匹配的起始结束位置. span() 返回了匹配位置的元组. 由于 match()仅仅检查一个字符串是否在起始位置匹配, start() 总是返回0,但是search() 会遍历整个字符串, 在下面的例子中匹配不一定是从0开始。.
>>>
>>> print(p.match('::: message'))
None
>>> m = p.search('::: message'); print(m)
<_sre.SRE_Match object at 0x...>
>>> m.group()
'message'
>>> m.span()
(4, 11)
是实际应用中,最常用的方式是将匹配对象存放在一个局部变量中,检查其是否是none,像下面这样:
p = re.compile( ... )
m = p.match( 'string goes here' )
if m:
print('Match found: ', m.group())
else:
print('No match')
有两个方法返回所有的匹配,一个是findall(),另外一个是finditer()。 findall()一个匹配列表:
>>>
>>> p = re.compile('\d+')
>>> p.findall('12 drummers drumming, 11 pipers piping, 10lords a-leaping')
['12', '11', '10']
finditer()返回一个匹配对象序列,物我们可以使用迭代器访问他们:
>>>
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> iterator
<callable_iterator object at 0x...>
>>> for match in iterator:
... print(match.span())
...
(0, 2)
(22, 24)
(29, 31)