我正在寻找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列表。 如何迭代所有组的匹配?
答案 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解析器;会让你的生活更轻松。