我正在尝试使用python和BeautifulSoup标记一个HTML文件(字面上用“mark”标签包装字符串)。问题基本上如下......
说我有原始的html文档:
test = "<h1>oh hey</h1><div>here is some <b>SILLY</b> text</div>"
我想对本文档中的字符串进行不区分大小写的搜索(忽略HTML)并将其包装在“mark”标记中。所以我想说我想在html中找到“这里有一些愚蠢的文字”(忽略粗体标签)。我想把匹配的html包装成“mark”标签。
例如,如果我想在测试中搜索“这里有一些愚蠢的文字”,那么所需的输出是:
"<h1>oh hey</h1><div><mark>here is some <b>SILLY</b> text</mark></div>"
有什么想法吗?如果使用lxml或正则表达式更合适,我也会对这些解决方案持开放态度。
答案 0 :(得分:5)
>>> 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>
我必须将一个函数作为name
传递给find_all
来比较x.text.lower()
,而不是仅使用text
参数和一个比较{x.lower()
的函数1}},后者在某些情况下找不到你想要的内容。
wrap
函数在某些情况下可能无法正常工作。如果没有,则必须改为enumerate(matches)
,并设置matches[i] = match.wrap(soup.new_tag('mark'))
。 (您无法使用replace_with
将标记替换为引用自身的新标记。)
另请注意,如果您的预期用例允许任何非ASCII字符串匹配'here is some silly text'
(或者如果您想扩展代码以处理非ASCII搜索字符串),则上面的代码使用{{1可能不正确。您可能需要致电lower()
和/或str.casefold()
和/或使用locale.strxfrm(s)
而不是使用locale.strcoll(s, t)
,但您必须了解您的需求以及如何获取它选择了正确的答案。