我在python中理解re.compile()方法有很多困难。我找到了这个例子,从我读到的它应该找到网页中的所有链接。它是否正确?有人可以解释表达式的"(。*?)部分吗?它对我来说没有多大意义,它似乎没有在页面中找到链接。
link_finder = re.compile('href="(.*?)"')
links = link_finder.findall(html)
答案 0 :(得分:1)
"(.*?)"
这是一个非贪婪的表达式,用于匹配一对双引号之间的所有字符。非贪婪意味着尽快,因为它会找到下一个双引号,它会停止搜索。
相比之下,贪婪的表达
"(.*)"
不会停在它找到的下一个双引号上 - 它会继续直到它击中当前行的最后一个 - 因此这个词是"贪婪的",而不是你需要的这种情况。
它可能无法为您找到任何内容,因为您使用single-quotes
代替double-quotes
引用了所有链接。在这种情况下,请尝试
link_finder = re.compile("href='(.*?)'")
而是(注意单引号和双引号的位置是交换的)
示例输出:
>>> link_finder = re.compile("href='(.*?)'")
>>> links = link_finder.findall("<a href='testlink'>")
>>> links
['testlink']
修改强>
作为免责声明,我应该注意到还有更好的方法可以做到这一点。一个如下:
re.compile("href\s*=\s*['\"](.*?)['\"]")
哪个匹配空格以及匹配两种类型的引号。但肯·汉普森建议使用专用工具lxml或Beautiful Soup更好。
答案 1 :(得分:1)
要真正找到文档中的所有 HTML 链接,它比正则表达式支持的更加细微。
例如,这些标记中的任何一个都是有效的HTML:
<a href='foo.html'>foo</a>
<a href = 'foo2.html'>foo2</a>
但是你的正则表达式只能找到第一个。
可以改变正则表达式来解释,是的,即:
link_finder = re.compile("href\s*=\s*'(.*?)'")
但除此之外还有其他细微差别(单引号和双引号对只是另一个例子),这又回到了关于使用正则表达式解析 HTML (也不是 XML 等)。最好使用实际的 HTML 解析器来实现这一点,因为所有这些细微差别都被考虑在内,因为解析器必须考虑整个语法语言。
如果您在网络环境中操作, jQuery 实际上可能是最好的选择,因为它会通过单行搜索 DOM 。< / p>
对于纯Python, lxml 是一种可能性(http://lxml.de/)。