Python:在元组中存储许多正则表达式匹配?

hao*_*ike 5 html python regex parsing

我正在尝试使用正则表达式制作一个简单的基于 Python 的 HTML 解析器。我的问题是试图让我的正则表达式搜索查询找到所有可能的匹配项,然后将它们存储在一个元组中。

假设我有一个页面,变量中存储了以下内容HTMLtext

<ul>
<li class="active"><b><a href="/blog/home">Back to the index</a></b></li>
<li><b><a href="/blog/about">About Me!</a></b></li>
<li><b><a href="/blog/music">Audio Production</a></b></li>
<li><b><a href="/blog/photos">Gallery</a></b></li>
<li><b><a href="/blog/stuff">Misc</a></b></li>
<li><b><a href="/blog/contact">Shoot me an email</a></b></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

我想对这个文本执行正则表达式搜索并返回一个包含每个链接的最后一个 URL 目录的元组。所以,我想返回这样的东西:

pages = ["home", "about", "music", "photos", "stuff", "contact"]
Run Code Online (Sandbox Code Playgroud)

到目前为止,我可以使用正则表达式来搜索一个结果:

pages = [re.compile('<a href="/blog/(.*)">').search(HTMLtext).group(1)]
Run Code Online (Sandbox Code Playgroud)

运行此表达式使pages = ['home'].

如何让正则表达式搜索继续整个文本,将匹配的文本附加到这个元组?

(注意:我知道我可能不应该使用正则表达式来解析 HTML。但无论如何我想知道如何做到这一点。)

tch*_*ist 2

您的模式不会\xe2\x80\x99 不适用于所有输入,包括您的输入。太贪婪了.*(从技术上讲,它找到了最大匹配),导致它成为第一个 href 和最后一个相应的 close。解决此问题的两种最简单的方法是使用最小匹配,或者使用否定字符类。

\n\n
# minimal match approach\npages = re.findall(r\'<a\\s+href="/blog/(.+?)">\', \n                   full_html_text, re.I + re.S)\n\n# negated charclass approach\npages = re.findall(r\'<a\\s+href="/blog/([^"]+)">\',\n                   full_html_text, re.I)\n
Run Code Online (Sandbox Code Playgroud)\n\n

强制性警告

\n\n

对于简单且约束良好的文本,正则表达式就可以了;毕竟,这就是为什么我们在编辑 HTML 时在文本编辑器中使用正则表达式搜索和替换的原因!然而,你对输入了解得越少,它就会变得越来越复杂,例如

\n\n
    \n
  • <a如果在和 之间存在\xe2\x80\x99s 一些其他字段href,例如<a title="foo" href="bar">
  • \n
  • 外壳问题,例如<A HREF=\'foo\'>
  • \n
  • 空白问题
  • \n
  • 替代引号,例如href=\'/foo/bar\'代替href="/foo/bar"
  • \n
  • 嵌入 HTML 注释
  • \n
\n\n

\xe2\x80\x99 并不是唯一的问题列表;还有其他的。因此,在 HTML 上使用正则表达式是可能的,但它是否有效取决于太多其他因素来判断。

\n\n

但是,从您\xe2\x80\x99 所示的小示例来看,它看起来非常适合您自己的情况。您只需改进您的模式并调用正确的方法即可。

\n