【问题标题】:Regular expression to extract URL from an HTML link从 HTML 链接中提取 URL 的正则表达式
【发布时间】:2010-10-04 16:51:07
【问题描述】:

我是 Python 的新手。我正在学习正则表达式,但在这里我需要帮助。

HTML 源代码来了:

<a href="http://www.ptop.se" target="_blank">http://www.ptop.se</a>

我正在尝试编写一个只打印出http://ptop.se 的工具。你能帮帮我吗?

【问题讨论】:

  • 我已经离开 SO 有一段时间了,很高兴看到我什么都没错过,人们仍然每天都在问如何用正则表达式解析 HTML。
  • @bobince 一天多次,太糟糕了,我创建了两个可以将人们重定向到的问题和一个指向他们那里的表单答案。

标签: python regex


【解决方案1】:

如果您只是在寻找一个:

import re
match = re.search(r'href=[\'"]?([^\'" >]+)', s)
if match:
    print(match.group(1))

如果你有一个长字符串,并且想要其中的每个模式实例:

import re
urls = re.findall(r'href=[\'"]?([^\'" >]+)', s)
print(', '.join(urls))

s 是您要在其中查找匹配项的字符串。

正则表达式位的快速解释:

r'...' 是一个“原始”字符串。它使您不必像往常一样担心转义字符。 (\ 尤其是 - 在原始字符串中,\ 只是 \。在常规字符串中,您每次都必须执行 \\,这会变得正则表达式。)

href=[\'"]?”表示匹配“href=”,可能后跟'"。 “可能”,因为很难说您正在查看的 HTML 有多糟糕,而且引号不是严格要求的。

将下一位包含在“()”中表示使其成为一个“组”,这意味着将其拆分并单独返回给我们。这只是表达“这是我感兴趣的模式的一部分”的一种方式。

[^\'" &gt;]+”表示匹配任何不是 '"&gt; 或空格的字符。本质上,这是作为 URL 结尾的字符列表。它让我们避免尝试编写一个可靠地匹配完整 URL 的正则表达式,这可能有点复杂。

另一个答案中使用 BeautifulSoup 的建议还不错,但它确实引入了更高级别的外部要求。此外,它并不能帮助您实现学习正则表达式的既定目标,我认为这个特定的 html 解析项目只是其中的一部分。

这很容易做到:

from BeautifulSoup import BeautifulSoup
soup = BeautifulSoup(html_to_parse)
for tag in soup.findAll('a', href=True):
    print(tag['href'])

无论如何,一旦你安装了 BeautifulSoup。

【讨论】:

  • 学习正则表达式的一部分是学习何时不使用它们,这是你不应该使用它们的情况。
  • 有些页面的格式非常糟糕,甚至 BeautifulSoup 也无法找到其中的链接。然后你必须求助于一些东西。
  • 对正则表达式的小改进:re.findall(r'href\s?=\s?[\'"]?([^\'" &gt;]+)', show_notes),允许在等号之前和/或之后有一个空格。
  • 你确定是“match.group(0)”而不是“match.group(1)”吗?
【解决方案2】:

你可以用这个。

<a[^>]+href=["'](.*?)["']

【讨论】:

    【解决方案3】:

    这个正则表达式可以帮助你,你应该通过 \1 或你的语言中的任何方法来获取第一组。

    href="([^"]*)
    

    示例:

    <a href="http://www.amghezi.com">amgheziName</a>
    

    结果:

    http://www.amghezi.com
    

    【讨论】:

      【解决方案4】:

      这非常适合使用可选匹配(在href= 之后打印)并且仅获取链接。测试于http://pythex.org/

      (?:href=['"])([:/.A-z?<_&\s=>0-9;-]+)
      

      输出:

      匹配 1。/wiki/Main_Page

      第 2 场比赛。/wiki/Portal:Contents

      第 3 场比赛。/wiki/Portal:Featured_content

      第 4 场比赛。/wiki/Portal:Current_events

      第 5 场比赛。/wiki/Special:Random

      第 6 场比赛。//donate.wikimedia.org/wiki/Special:FundraiserRedirector?utm_source=donate&utm_medium=sidebar&utm_campaign=C13_en.wikipedia.org&uselang=en

      【讨论】:

      • 当在python程序中输入这个正则表达式时(不是通过你提到的站点),由于使用了文本引号'",它会出错。要解决此问题,正则表达式应为:regex='(?:href=[\'"])([:/.A-z?&lt;_&amp;\s=&gt;0-9;-]+)',在 '" 之前添加一个斜线 \。
      【解决方案5】:

      John Gruber(他编写了 Markdown,它由正则表达式组成,并在 Stack Overflow 上使用)尝试生成一个识别文本中 URL 的正则表达式:

      http://daringfireball.net/2009/11/liberal_regex_for_matching_urls

      如果你只是想获取 URL(即你不是真的试图解析 HTML),这可能比 HTML 解析器更轻量。

      【讨论】:

        【解决方案6】:

        正则表达式根本不擅长解析 HTML(请参阅 Can you provide some examples of why it is hard to parse XML and HTML with a regex? 了解原因)。您需要的是一个 HTML 解析器。有关使用各种解析器的示例,请参阅 Can you provide an example of parsing HTML with your favorite parser?

        您尤其需要查看 Python 答案:BeautifulSoupHTMLParserlxml

        【讨论】:

          【解决方案7】:

          是的,regexlib 上有很多。这只能证明不应该使用 RE 来做到这一点。使用 SGMLParser 或 BeautifulSoup 或编写解析器 - 但不要使用 RE。似乎有效的那些非常复杂,但仍不能涵盖所有情况。

          【讨论】:

            【解决方案8】:

            regexlib 上有很多这样的人

            【讨论】:

              【解决方案9】:

              这应该可行,尽管可能有更优雅的方法。

              import re
              url='<a href="http://www.ptop.se" target="_blank">http://www.ptop.se</a>'
              r = re.compile('(?<=href=").*?(?=")')
              r.findall(url)
              

              【讨论】:

              • (?
              【解决方案10】:

              不要使用正则表达式,使用BeautifulSoup。那,或者太粗鲁以至于将其生成到 w3m/lynx 并拉回 w3m/lynx 渲染的内容。第一个可能更优雅,第二个在我不久前编写的一些未优化代码上运行得更快。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-09-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-05-31
                • 2023-03-27
                • 2013-08-28
                相关资源
                最近更新 更多