Мне нужно отфильтровать довольно длинный (но очень регулярный) набор файлов .html, чтобы изменить несколько конструкций только , если они появляются в текстовых элементах.
Один хороший пример -измените <p><div class="speech">it's hard to find his "good" side! He has <i>none</i>!<div></p>
на <p><div class="speech">it's hard to find his “good” side! He has <i>none</i>!<div></p>
.
Я могу легко проанализировать свои файлы с помощью html.parser
, но неясно, как сгенерировать файл результатов, который должен быть максимально похож на ввод (без переформатирования).
Я посмотрел на Beautiful-Soup, но он действительно кажется слишком большим для этой (предположительно?) Простой задачи.
Примечание: я не нуждаюсь / хочуобслуживать файлы .html в любом браузере;Мне просто нужно, чтобы они были обновлены (возможно на месте) с (слегка) измененным содержимым.
ОБНОВЛЕНИЕ:
Следуя совету @soundstripe, я написал следующий код:
import bs4
from re import sub
def handle_html(html):
sp = bs4.BeautifulSoup(html, features='html.parser')
for e in list(sp.strings):
s = sub(r'"([^"]+)"', r'“\1”', e)
if s != e:
e.replace_with(s)
return str(sp).encode()
raw = b"""<p><div class="speech">it's hard to "find" his "good" side! He has <i>none</i>!<div></p>"""
new = handle_html(raw)
print(raw)
print(new)
К сожалению, BeautifulSoup пытается быть слишком умным из своего (и моего) собственного блага:
b'<p><div class="speech">it\'s hard to "find" his "good" side! He has <i>none</i>!<div></p>'
b'<p><div class="speech">it\'s hard to &ldquo;find&rdquo; his &ldquo;good&rdquo; side! He has <i>none</i>!<div></div></div></p>'
, то есть: он преобразует простой &
в &
, тем самым нарушая сущность “
(обратите внимание, что я работаю сbytearrays, а не strings. Это актуально?).
Как это исправить?