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

Jas*_*n S 6 html python regex beautifulsoup

我希望BeautifulSoup等同于这个jQuery问题.

我想在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>
Run Code Online (Sandbox Code Playgroud)

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

<html><body><p><b>Snook</b> as a <b>book</b> in a <b>rook</b></p></body></html>
Run Code Online (Sandbox Code Playgroud)

roi*_*ppi 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>
Run Code Online (Sandbox Code Playgroud)

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

'html.parser'内部BeautifulSoup调用有点神奇的论点是阻止它添加<html><body><p>标签,比如bs4(嗯,lxml)通常会这样做. 更多阅读.


mda*_*adm 2

所以这是一种方法。您可以使用正则表达式创建新的 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
Run Code Online (Sandbox Code Playgroud)

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