Как я могу удалить <p></p> с Python Sub - PullRequest
3 голосов
/ 23 марта 2011

У меня есть HTML-файл, и я хочу заменить пустые абзацы пробелом.

mystring = "This <p></p><p>is a test</p><p></p><p></p>"
result = mystring.sub("<p></p>" , "&nbsp;")

Это не работает.

Ответы [ 6 ]

10 голосов
/ 23 марта 2011

Пожалуйста, не пытайтесь анализировать HTML с помощью регулярных выражений . Для этого используйте подходящий модуль синтаксического анализа, например htmlparser или BeautifulSoup. «Потерпи» короткую кривую обучения сейчас и получи выгоду:

  1. Ваш код синтаксического анализа будет более надежным, обрабатывая угловые случаи, которые вы, возможно, не рассматривали, которые не пройдут с помощью регулярного выражения
  2. Для будущих задач анализа / разбора HTML вы будете иметь возможность делать вещи быстрее, поэтому в конечном итоге затраты времени также окупятся.

Ты не пожалеешь! Прибыль гарантирована!

5 голосов
/ 23 марта 2011

Я думаю, что всегда приятно привести пример того, как это сделать с реальным парсером, а также просто повторить звуковой совет, который Эли Бендерский дает в своем ответе.

Вот пример того, как удалить пустые <p> элементы, используя lxml .HTMLParser в lxml отлично работает с HTML.

from lxml import etree
from StringIO import StringIO

input = '''This <p> </p><p>is a test</p><p></p><p><b>Bye.</b></p>'''

parser = etree.HTMLParser()
tree = etree.parse(StringIO(input), parser)

for p in tree.xpath("//p"):
    if len(p):
        continue
    t = p.text
    if not (t and t.strip()):
        p.getparent().remove(p)

print etree.tostring(tree.getroot(), pretty_print=True)

..., который выдает:

<html>
  <body>
    <p>This </p>
    <p>is a test</p>
    <p>
      <b>Bye.</b>
    </p>
  </body>
</html>

Обратите внимание, что при ответе на этот вопрос я неправильно прочитал вопрос,и я только удаляю пустые элементы <p>, а не заменяю их на &nbsp.С lxml я не уверен в простом способе сделать это, поэтому я создал еще один вопрос:

2 голосов
/ 23 марта 2011

Что, если <p> введен как <P>, или < p >, или к нему добавлен атрибут, или задан с использованием синтаксиса пустого тега <P/>? Поддержка HTML-тегов Pyparsing обрабатывает все эти варианты:

from pyparsing import makeHTMLTags, replaceWith, withAttribute

mystring = 'This <p></p><p>is a test</p><p align="left"></p><P> </p><P/>'

p,pEnd = makeHTMLTags("P")
emptyP = p.copy().setParseAction(withAttribute(empty=True))

null_paragraph = emptyP | p+pEnd
null_paragraph.setParseAction(replaceWith("&nbsp;"))

print null_paragraph.transformString(mystring)

Печать:

This &nbsp;<p>is a test</p>&nbsp;&nbsp;&nbsp;
2 голосов
/ 23 марта 2011

Я думаю, что для этой конкретной проблемы модуль синтаксического анализа был бы излишним

просто эта функция:

>>> mystring = "This <p></p><p>is a test</p><p></p><p></p>"

>>> mystring.replace("<p></p>","&nbsp;")
'This &nbsp;<p>is a test</p>&nbsp;&nbsp;'
1 голос
/ 23 марта 2011

с использованием регулярных выражений?

import re
result = re.sub("<p>\s*</p>","&nbsp;", mystring, flags=re.MULTILINE)

скомпилируйте регулярное выражение, если вы часто его используете.

0 голосов
/ 12 апреля 2012

Я написал этот код:

from lxml import etree
from StringIO import StringIO

html_tags = """<div><ul><li>PID temperature controller</li> <li>Smart and reliable</li> <li>Auto-diagnosing</li> <li>Auto setting</li> <li>Intelligent control</li> <li>2-Rows 4-Digits LED display</li> <li>Widely applied in the display and control of the parameter of temperature, pressure, flow, and liquid level</li> <li>     </li> <p> </p></ul> <div> </div></div>"""

document = etree.iterparse(StringIO(html_tags), html=True)

for a, e in document:
    if not (e.text and e.text.strip()) and len(e) == 0:
        e.getparent().remove(e)

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