Регулярное выражение Python для нескольких тегов - PullRequest
2 голосов
/ 10 июня 2009

Я хотел бы знать, как получить все результаты из каждого тега <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 ]

11 голосов
/ 10 июня 2009

Для этого типа проблемы рекомендуется использовать анализатор DOM, а не регулярное выражение.

Я видел Красивый суп , часто рекомендуемый для Python

5 голосов
/ 10 июня 2009

Красивый суп - это, безусловно, способ решить такую ​​проблему. Код чище и проще для чтения. После установки все теги выглядят примерно так.

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.

4 голосов
/ 10 июня 2009

Регулярный ответ чрезвычайно хрупок. Вот доказательство (и рабочий пример 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.

2 голосов
/ 10 июня 2009

Либо 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')
2 голосов
/ 10 июня 2009

Вы можете использовать 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 обычно является плохой идеей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...