【问题标题】:Python regular expression for multiple tags用于多个标签的 Python 正则表达式
【发布时间】:2010-11-01 15:30:28
【问题描述】:

我想知道如何从每个<p> 标记中检索所有结果。

import re
htmlText = '<p data="5" size="4">item1</p><p size="4">item2</p><p size="4">item3</p>'
print re.match('<p[^>]*size="[0-9]">(.*?)</p>', htmlText).groups()

结果:

('item1', )

我需要什么:

('item1', 'item2', 'item3')

【问题讨论】:

  • -1 用于尝试使用正则表达式解析非常规语言。
  • 同意,不是有一个以解析html而闻名的python库吗?美丽汤? htmllib?
  • 感谢您的回复。我需要一种 python 方法来从一个小 html 中打印出 p 标记的所有值,而无需在服务器中安装任何新内容。

标签: python html regex


【解决方案1】:

你可以像这样使用re.findall

import re
html = '<p data="5" size="4">item1</p><p size="4">item2</p><p size="4">item3</p>'
print re.findall('<p[^>]*size="[0-9]">(.*?)</p>', html)
# This prints: ['item1', 'item2', 'item3']

编辑:...但正如许多评论者指出的那样,使用正则表达式解析 HTML 通常是一个坏主意。

【讨论】:

  • 谢谢!我刚刚在 Python 文档上找到了它! docs.python.org/dev/howto/regex.html
  • 很抱歉,这是一个糟糕的答案。如果 size 属性和右括号之间有空格怎么办:

    ?

  • @Triptych:没有。您是否考虑过 OP 知道他在做什么的可能性? 8-) 问题是“我如何解析这个 HTML?”那么我不会建议使用正则表达式。但它是“如何使我的正则表达式工作?”,这是对这个问题的回答。
  • -1:给出了一个正则表达式解析html的例子,甚至没有说这真的很糟糕,很多新手都会读。邪恶来自这样的行为。
  • @RichieHindle:原始发帖人没有说任何关于使正则表达式工作的内容。他说他想从每个 p 标签中检索结果。正则表达式不适合这样做。
【解决方案2】:

对于此类问题,建议使用 DOM 解析器,而不是正则表达式。

我看到Beautiful Soup 经常被推荐用于 Python

【讨论】:

    【解决方案3】:

    或者,xml.dom.minidom 将解析您的 HTML,如果,

    • ...格式正确
    • ...您将其嵌入到单个根元素中。

    例如,

    >>> import xml.dom.minidom
    >>> htmlText = '<p data="5" size="4">item1</p><p size="4">item2</p><p size="4">item3</p>'
    >>> d = xml.dom.minidom.parseString('<not_p>%s</not_p>' % htmlText)
    >>> tuple(map(lambda e: e.firstChild.wholeText, d.firstChild.childNodes))
    ('item1', 'item2', 'item3')
    

    【讨论】:

      【解决方案4】:

      美丽的汤绝对是解决此类问题的方法。代码更简洁,更易于阅读。一旦你安装了它,所有的标签看起来都是这样的。

      from BeautifulSoup import BeautifulSoup
      import urllib2
      
      def getTags(tag):
        f = urllib2.urlopen("http://cnn.com")
        soup = BeautifulSoup(f.read())
        return soup.findAll(tag)
      
      
      if __name__ == '__main__':
        tags = getTags('p')
        for tag in tags: print(tag.contents)
      

      这将打印出 p 标签的所有值。

      【讨论】:

      • 感谢您的回复。我只需要一种 python 方法来打印出 p 标签的所有值,而无需在服务器中安装任何新东西。
      【解决方案5】:

      正则表达式的答案非常脆弱。这是证明(以及一个有效的 BeautifulSoup 示例)。

      from BeautifulSoup import BeautifulSoup
      
      # Here's your HTML
      html = '<p data="5" size="4">item1</p><p size="4">item2</p><p size="4">item3</p>'
      
      # Here's some simple HTML that breaks your accepted 
      # answer, but doesn't break BeautifulSoup.
      # For each example, the regex will ignore the first <p> tag.
      html2 = '<p size="4" data="5">item1</p><p size="4">item2</p><p size="4">item3</p>'
      html3 = '<p data="5" size="4" >item1</p><p size="4">item2</p><p size="4">item3</p>'
      html4 = '<p data="5" size="12">item1</p><p size="4">item2</p><p size="4">item3</p>'
      
      # This BeautifulSoup code works for all the examples.
      paragraphs = BeautifulSoup(html).findAll('p')
      items = [''.join(p.findAll(text=True)) for p in paragraphs]
      

      使用 BeautifulSoup。

      【讨论】:

      • 我认为你不需要导入 re.另外,我很好奇你的例子提供了什么,而我的例子除了列表理解之外没有。
      • Brett - 我的将正确处理像

        item1

        这样的情况,而你的会失败。此外,此处的 items 数组将转换为字符串列表,而您的示例将返回 tag.contents,这实际上是一个(非常消耗内存的)BeautifulSoup 对象。
      • 酷!我不知道该对象是内存密集型的,我只在小型解析项目中使用过它,从未遇到过问题。感谢更新。我根据你的解释投了你的票。
      • 我使用 BeautifulSoup 处理一些非常大 (500KB+) 的 HTML 文件,如果你不学会节省内存,你就会遇到一堵难关。 BeautifulSoup 非常方便,但效率不高。
      猜你喜欢
      • 1970-01-01
      • 2015-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-12
      • 1970-01-01
      • 2016-12-21
      相关资源
      最近更新 更多