在BeautifulSoup中包含带有标签的文本子部分

时间:2014-03-27 22:32:49

标签: python html regex beautifulsoup

我希望BeautifulSoup等同于this jQuery question

我想在BeautifulSoup文本中找到特定的正则表达式匹配,然后用包装版本替换该段文本。我可以用明文包装来做到这一点:

# replace all words ending in "ug" wrapped in quotes,
# with "ug" replaced with "ook"

>>> soup = BeautifulSoup("Snug as a bug in a rug")
>>> soup
<html><body><p>Snug as a bug in a rug</p></body></html>
>>> for text in soup.findAll(text=True):
...   if re.search(r'ug\b',text):
...     text.replaceWith(re.sub(r'(\w*)ug\b',r'"\1ook"',text))
...
u'Snug as a bug in a rug'
>>> soup
<html><body><p>"Snook" as a "book" in a "rook"</p></body></html>

但是,如果我想要粗体而不是引号呢?例如期望的结果=

<html><body><p><b>Snook</b> as a <b>book</b> in a <b>rook</b></p></body></html>

2 个答案:

答案 0 :(得分:5)

for text in soup.findAll(text=True):
   if re.search(r'ug\b',text):
     text.replaceWith(BeautifulSoup(re.sub(r'(\w*)ug\b',r'<b>\1ook</b>',text),'html.parser'))

soup
Out[117]: <html><body><p><b>Snook</b> as a <b>book</b> in a <b>rook</b></p></body></html>

这里的想法是我们用完全形成的解析树替换标签。最简单的方法是在我们的正则表达式子字符串上调用BeautifulSoup

内部'html.parser'调用的有点神奇BeautifulSoup参数是阻止它添加<html><body><p>标记,例如bs4(嗯,lxml)通常会这样做。 More reading on that.

答案 1 :(得分:3)

所以这是一种方法。您可以使用正则表达式创建包含粗体字围绕的单词的新HTML,将其放入BeautifulSoup构造函数中,并用新的p标签替换整个父p。

import bs4
import re

soup = bs4.BeautifulSoup("Snug as a bug in a rug")
print soup

for text in soup.findAll(text=True):
    if re.search(r'ug\b',text):
        new_html = "<p>"+re.sub(r'(\w*)ug\b', r'<b>\1ook</b>', text)+"</p>"
        new_soup = bs4.BeautifulSoup(new_html)
        text.parent.replace_with(new_soup.p)

print soup

另一种选择是使用soup.new_tag方法,但这可能需要嵌套的for循环,这不会那么优雅。我会看看我是否可以写下来并在以后发布。