【问题标题】:Python -- Regex -- How to find a string between two sets of stringsPython -- 正则表达式 -- 如何在两组字符串之间找到一个字符串
【发布时间】:2010-10-25 09:29:19
【问题描述】:

考虑以下几点:

<div id=hotlinklist>
  <a href="foo1.com">Foo1</a>
  <div id=hotlink>
    <a href="/">Home</a>
  </div>
  <div id=hotlink>
    <a href="/extract">Extract</a>
  </div>
  <div id=hotlink>
    <a href="/sitemap">Sitemap</a>
  </div>
</div>

您将如何在 python 中使用正则表达式取出站点地图行?

<a href="/sitemap">Sitemap</a>

以下可以用来拉出锚标签。

'/<a(.*?)a>/i'

但是,有多个锚标记。还有多个热链接,所以我们也不能真正使用它们吗?

【问题讨论】:

  • 你可能会听说正则表达式不适合解析像 HTML 这样的上下文无关语言。
  • 如果您是生成该 HTML 的人,值得注意的是,多个相同的 id= 属性是无效的。 class= 更合适。

标签: python regex string tags


【解决方案1】:

不要使用正则表达式。使用BeautfulSoup,一个 HTML 解析器。

from BeautifulSoup import BeautifulSoup

html = \
"""
<div id=hotlinklist>
  <a href="foo1.com">Foo1</a>
  <div id=hotlink>
    <a href="/">Home</a>
  </div>
  <div id=hotlink>
    <a href="/extract">Extract</a>
  </div>
  <div id=hotlink>
    <a href="/sitemap">Sitemap</a>
  </div>
</div>"""

soup = BeautifulSoup(html)
soup.findAll("div",id="hotlink")[2].a

# <a href="/sitemap">Sitemap</a>

【讨论】:

    【解决方案2】:

    用正则表达式解析 HTML 是个坏主意!

    想想下面这段 html

    <a></a > <!-- legal html, but won't pass your regex -->
    
    <a href="/sitemap">Sitemap<!-- proof that a>b iff ab>1 --></a>
    

    这样的例子还有很多。正则表达式适用于很多事情,但不适用于解析 HTML。

    您应该考虑使用Beautiful Soup python HTML 解析器。

    无论如何,使用正则表达式的临时解决方案是

    import re
    
    data = """
    <div id=hotlinklist>
      <a href="foo1.com">Foo1</a>
      <div id=hotlink>
        <a href="/">Home</a>
      </div>
      <div id=hotlink>
        <a href="/extract">Extract</a>
      </div>
      <div id=hotlink>
        <a href="/sitemap">Sitemap</a>
      </div>
    </div>
    """
    
    e = re.compile('<a *[^>]*>.*</a *>')
    
    print e.findall(data)
    

    输出:

    >>> e.findall(data)
    ['<a href="foo1.com">Foo1</a>', '<a href="/">Home</a>', '<a href="/extract">Extract</a>', '<a href="/sitemap">Sitemap</a>']
    

    【讨论】:

    • 如果您将 .* 替换为 (?:[^&lt;]+|&lt;(!/a\b))*,您将获得更少的误报,而不会因回溯而破坏正则表达式引擎。
    【解决方案3】:

    为了提取标语的内容:

        <a href="/sitemap">Sitemap</a>
    

    ...我会使用:

        >>> import re
        >>> s = '''
        <div id=hotlinklist>
        <a href="foo1.com">Foo1</a>
          <div id=hotlink>
            <a href="/">Home</a>
          </div>
          <div id=hotlink>
            <a href="/extract">Extract</a>
          </div>
          <div id=hotlink>
            <a href="/sitemap">Sitemap</a>
          </div>
        </div>'''
        >>> m = re.compile(r'<a href="/sitemap">(.*?)</a>').search(s)
        >>> m.group(1)
        'Sitemap'
    

    【讨论】:

    • 实际上,用 XYZ 替换站点地图,因为它真的可以是任何东西。我只知道它是 hotlinlist div 中的第三个 div。使用的 html 模式可以重复多次。假设我想取出 ebay 上列出的所有智能手机。我知道对于找到的每部智能手机都会重复上述模式,但是,XYZ 可以是 iphone、黑莓、诺基亚或任何其他智能手机。可能没有项目或 100 个。所以,我一直在寻找说找到重复模式的东西,然后拿出智能手机线并列出智能手机。
    • 我喜欢这个,因为它回答了这个问题。它还帮助我更好地理解正则表达式,信不信由你。
    【解决方案4】:

    如果需要解析 HTML,请使用 BeautifulSouplxml

    另外,你真正需要做什么?找到最后一个链接?找到第三个链接?找到指向 /sitemap 的链接?你的问题不清楚。您需要对数据做什么

    如果您真的必须使用正则表达式,请查看findall

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-19
      • 2012-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-27
      • 1970-01-01
      相关资源
      最近更新 更多