【问题标题】:How to find all occurrences when a prefix is present存在前缀时如何查找所有匹配项
【发布时间】:2012-12-19 23:12:56
【问题描述】:

我正在寻找 HTML 页面中的重复模式。
我感兴趣的模式在前缀“

Seasons

”之后开始
同样的模式也出现在前缀之前,我对那些不感兴趣。

我尝试使用以下 python 代码(但失败了)(我将模式简化为 '' 为了使这个问题易于阅读):

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 列表。 如何遍历组的所有匹配项?

【问题讨论】:

  • 这可能是问题所在:regular-expressions.info/captureall.html
  • 当有许多出色的 HTML 解析器可以更好地完成这项工作并使其更容易时,您为什么还要尝试使用正则表达式来解析 HTML?

标签: python regex iterator


【解决方案1】:

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

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

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

这表示查找&lt;a&gt; 元素,但前提是它们前面有&lt;h2&gt;Seasons&lt;/h2&gt;。不幸的是,lookbehind 字符串必须是固定长度的。您不能将 .+? 放在后向断言中。所以这种方法已经过时了。

接下来是先找到&lt;h2&gt;元素的位置,然后从那里开始进行正则表达式搜索。

>>> 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>']

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我认为 HTML 解析器对于我想做的事情来说太过分了
    猜你喜欢
    • 2017-12-05
    • 1970-01-01
    • 2016-05-31
    • 1970-01-01
    • 2021-10-17
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    相关资源
    最近更新 更多