Python 按文本查找并在HTML BeautifulSoup中替换

Python 按文本查找并在HTML BeautifulSoup中替换,python,regex,html-parsing,beautifulsoup,lxml,Python,Regex,Html Parsing,Beautifulsoup,Lxml,我正在尝试使用python和BeautifulSoup标记一个HTML文件(字面上是用“标记”标记包装字符串)。问题基本上如下 假设我有我的原始html文档: test = "<h1>oh hey</h1><div>here is some <b>SILLY</b> text</div>" test=“哦,嘿,这里有一些愚蠢的文字” 我想对文档中的字符串进行不区分大小写的搜索(忽略HTML),并将其包装在“mark”标记

我正在尝试使用python和BeautifulSoup标记一个HTML文件(字面上是用“标记”标记包装字符串)。问题基本上如下

假设我有我的原始html文档:

test = "<h1>oh hey</h1><div>here is some <b>SILLY</b> text</div>"
test=“哦,嘿,这里有一些愚蠢的文字”
我想对文档中的字符串进行不区分大小写的搜索(忽略HTML),并将其包装在“mark”标记中。假设我想在html中找到“这是一些愚蠢的文本”(忽略粗体标记)。我想获取匹配的html并将其包装在“mark”标记中

例如,如果我想在测试中搜索“这是一些愚蠢的文本”,那么所需的输出是:

"<h1>oh hey</h1><div><mark>here is some <b>SILLY</b> text</mark></div>"
“哦,嘿,这里有一些愚蠢的文字”
有什么想法吗?如果更适合使用lxml或正则表达式,我也愿意接受这些解决方案。

>soup=bs4.BeautifulSoup(test)
>>> soup = bs4.BeautifulSoup(test)
>>> matches = soup.find_all(lambda x: x.text.lower() == 'here is some silly text')
>>> for match in matches:
...     match.wrap(soup.new_tag('mark'))
>>> soup
<html><body><h1>oh hey</h1><mark><div>here is some <b>SILLY</b> text</div></mark></body></html>
>>>matches=soup.find_all(lambda x:x.text.lower()=='这是一些愚蠢的文本') >>>对于匹配中的匹配: ... 匹配。包装(汤。新标签('mark')) >>>汤 哦,嘿,这里有一些愚蠢的文字
我必须将一个函数作为
name
传递给比较
x.text.lower()
find_all
,而不是将
text
参数与比较
x.lower()
的函数一起使用,原因是后者在某些情况下找不到您显然想要的内容

在某些情况下,
wrap
功能可能无法以这种方式工作。如果没有,则必须改为
枚举(匹配项)
,并设置
匹配项[i]=match.wrap(soup.new_标记('mark'))
。(不能使用
replace_with
将标记替换为引用自身的新标记。)


另外请注意,如果您的预期用例允许任何非ASCII字符串与
“这里有一些愚蠢的文本”
(或者如果您希望扩展代码以处理非ASCII搜索字符串),则上面使用
lower()的代码可能不正确。您可能想调用
str.casefold()
和/或
locale.strxfrm
和/或使用
locale.strcoll(s,t)
,而不是使用
=
,但您必须了解您想要什么,以及如何让它选择正确的答案。

接近另一个问题的副本@melwil-很接近,但仅涵盖问题的(区分大小写)文本检索部分。如何使用类似的搜索字符串,在html中查找不区分大小写的匹配项,并将这些匹配项包装在标记标记中?一旦找到文本,只需将其插入标记标记中包含的父项中即可。您想如何处理
以下是一些愚蠢的文本
?如果将其转换为
,这里有一些愚蠢的文本
,那么
标记
跨越两个同级元素。“可以吗?”凯文-是的!我很好,非常感谢!看起来你可以在matches:match.wrap(soup.new_tag('mark'))中对match进行
@MuradSalahi:我刚刚测试了一下。它似乎在4.1.3中起作用,但在4.0.5中不起作用。我不知道为什么,但我会把它改成简单的版本,并给出解释,或者对任何不适合它的人。谢谢@塞巴斯蒂安:是的。但是如果不知道用例,就不可能描述什么是正确的。我会更新答案来涵盖这一点。如果我想要的是“愚蠢的文本”怎么办?它跨越2个标签,所以你无法通过iter所有标签找到它。