多个标签的Python正则表达式

时间:2009-06-09 22:09:22

标签: python html regex

我想知道如何从每个<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')

5 个答案:

答案 0 :(得分:11)

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

我经常看到{<3}}经常推荐用于Python

答案 1 :(得分:5)

美丽的汤肯定是这样一个问题的方法。代码更清晰,更易于阅读。安装完成后,获取所有标签就像这样。

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标签的所有值。

答案 2 :(得分:4)

正则表达式的答案非常脆弱。这是证据(以及一个有效的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。

答案 3 :(得分:2)

您可以像这样使用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通常是一个坏主意。

答案 4 :(得分:2)

或者,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')