2

嗨,我有一个正则表达式
<a href="(.+?)" class="nextpostslink">

此正则表达式适用于以下 html
'> <span class='pages'>Page 1 of 12</span><span class='current'>1</span><a href='http://cinemassacre.com/category/avgn/page/2/' class='page larger'>2</a><a href='http://cinemassacre.com/category/avgn/page/3/' class='page larger'>3</a><a href='http://cinemassacre.com/category/avgn/page/4/' class='page larger'>4</a><a href='http://cinemassacre.com/category/avgn/page/5/' class='page larger'>5</a><a href="http://cinemassacre.com/category/avgn/page/2/" class="nextpostslink">&raquo;</a><span class='extend'>...</span><a href='http://cinemassacre.com/category/avgn/page/12/' class='last'>Last &raquo;</a> </div> </div>

我试图提取的部分是下一页的网址
<a href="http://cinemassacre.com/category/avgn/page/2/" class="nextpostslink">

但是当我在这个 HTML 块上运行这个正则表达式时
'> <span class='pages'>Page 2 of 12</span><a href="http://cinemassacre.com/category/avgn/" class="previouspostslink">&laquo;</a><a href='http://cinemassacre.com/category/avgn/' class='page smaller'>1</a><span class='current'>2</span><a href='http://cinemassacre.com/category/avgn/page/3/' class='page larger'>3</a><a href='http://cinemassacre.com/category/avgn/page/4/' class='page larger'>4</a><a href='http://cinemassacre.com/category/avgn/page/5/' class='page larger'>5</a><a href="http://cinemassacre.com/category/avgn/page/3/" class="nextpostslink">&raquo;</a><span class='extend'>...</span><a href='http://cinemassacre.com/category/avgn/page/12/' class='last'>Last &raquo;</a> </div>
</div>


它提取从第一个<a href="" class="nextpostslink">
为什么会发生这种情况的所有内容?我认为 (.+?) 是非贪婪的,所以它应该提取最少的数量。
哪个应该是<a href="http://cinemassacre.com/category/avgn/page/3/" class="nextpostslink">

我使用的完整python代码是
match=re.compile('<a href="(.+?)" class="nextpostslink">', re.DOTALL).findall(pagenav)

4

3 回答 3

3

据我了解,贪婪从正则表达式的开头开始起作用——即,它找到<a href=",然后非贪婪让它停在第一个 " class="nextpostslink">而不是最后一个,就像贪婪版本一样。

你最好在这里使用BeautifulSoup

from bs4 import BeautifulSoup as BS
soup = BS(html)
print soup.find("a", "nextpostslink").attrs['href']
# returns u'http://cinemassacre.com/category/avgn/page/2/'
于 2012-12-04T19:49:38.470 回答
3

从某种意义上说,比赛的开始总是很贪婪。这是因为引擎尝试在您的主题字符串中从左到右进行匹配。遇到第一个<a href=",这很好,然后引擎继续并消耗所有内容,.+?直到匹配完成(由于 ,它会尽快停止.+?)。但它并没有尝试尽可能向右开始比赛,因为比赛很好。因此,您可以说 using?使比赛结束不贪心(取比赛的第一个可能结束),但比赛的开始将始终是贪心的(无论您如何,比赛将始终从最左边的可能位置开始试着让它变得不贪心)。

这就是为什么通常有更好的替代不贪婪重复的方法:从重复中排除分隔符:

<a href="([^"]*)" class="nextpostslink">

这永远不会超过结束",因此无需担心属性或标签之外的任何内容都会成为匹配的一部分。

无论如何,让我补充一点,您不应该使用正则表达式来解析 HTML。如果'使用而不是"(如给定示例中的第二个锚标记)怎么办?如果您的属性之间有多个空格怎么办?如果有更多的属性而不仅仅是hrefandclass怎么办?如果class属性列在href属性之前怎么办?

jdotjdot 的答案有一个很好的例子,说明如何在 Python 中以正确的方式做到这一点。

于 2012-12-04T19:47:06.287 回答
1

它从第一个中提取所有内容 为什么会发生这种情况?我认为 (.+?) 是非贪婪的,所以它应该提取最少的量

它是非贪婪的。但是,您有一个强制性的class="nextpostslink">正则表达式这一事实会迫使引擎匹配所有内容,直到找到class="nextpostslink">.

于 2012-12-04T19:47:11.010 回答