如何在存在前缀时查找所有匹配项

时间:2012-12-19 23:12:56

标签: python regex iterator

我正在寻找HTML页面内的重复模式 我感兴趣的模式在前缀“< h2> Seasons< / h2>”之后开始 相同的模式也出现在前缀之前,我对这些模式不感兴趣。

我尝试(并且失败)使用以下python代码(为了使这个问题可读,我将模式简化为'< a href =。+?< / a>'):

matches = re.compile('<h2>Seasons</h2>.+?(<a href=.+?</a>)+',re.DOTALL).findall(page)  
for ref in matches  
   print ref

鉴于页面:

blah blah html stuff 
<h2>Seasons</h2>  
blah blah  more html stuff
<a href=http://www.111.com>111</a><a href=http://www.222.com>222</a><a href=http://www.333.com>333</a>

输出

<a href=http://www.333.com>333</a>  

所以它只打印最后一个匹配,另外两个不会进入findall列表。 如何迭代所有组的匹配?

2 个答案:

答案 0 :(得分:2)

问题是正则表达式只匹配一次。带括号的组匹配多次,但正则表达式整体只匹配一次。这意味着只返回一个匹配,即最后一个匹配。

要解决这个问题,你需要编写一个匹配多次的正则表达式。您可能会考虑对<h2>元素使用lookbehind断言,如下所示:

(?<=<h2>Seasons</h2>.+?)(<a href=.+?</a>)    # doesn't work

这表示找到<a>个元素,但前提是它们前面有<h2>Seasons</h2>。不幸的是,后面的字符串必须是固定长度的。你不能把.+?置于一个后瞻性的断言中。所以这种方法已经结束了。

接下来是首先找到<h2>元素的位置,然后从那里开始执行正则表达式搜索。

>>> re.findall('<a href=.+?</a>', page[page.find('<h2>Seasons</h2>'):], re.DOTALL)
['<a href=http://www.111.com>111</a>', '<a href=http://www.222.com>222</a>', '<a href=http://www.333.com>333</a>']

答案 1 :(得分:1)

你应该使用像BeautifulSoup这样的html解析器;会让你的生活更轻松。