能否用正则表达式清除HTML节点所有文本?含代码尝试与问题
清除HTML节点所有文本:正则可行吗?怎么用BeautifulSoup搞定?
一、正则的坑:看起来能用,但隐患大
你的正则代码在这个简单HTML案例里能正常跑,但绝对不推荐用正则处理HTML,踩坑是迟早的事:
- 遇到HTML注释、CDATA块时,里面的
</>会被误匹配,破坏原有结构 - 如果标签属性里包含
<或>(比如<div title="a>b">),正则会错误修改属性内容 - 复杂嵌套、多行文本的场景下,正则很容易漏匹配或错匹配
二、BeautifulSoup的正确打开方式
你之前的代码没处理掉“4”,是因为n.string只在节点是纯文本叶子节点时才返回内容。像<strong>这种下面既有<span>又有文本“4”的节点,n.string是None,循环直接跳过了里面的文本节点。
直接定位所有文本节点(NavigableString类型)来清空就行,看代码:
from bs4 import BeautifulSoup, NavigableString from htmlmin import minify html = """ <li class="menu-item"> <p class="menu-item__heading">Totopos</p> <p>Chips and molcajete salsa</p> <p class="menu-item__details menu-item__details--price"> <strong> <span class="menu-item__currency"> $ </span> 4 </strong> </p> </li> """ soup = BeautifulSoup(html, "html.parser") # 找到所有文本节点,替换为空 for string in soup.find_all(string=True): string.replace_with("") print(minify(str(soup)))
要是喜欢递归写法,也可以这么搞,适配更复杂的嵌套:
def clear_all_text(node): # 遍历节点的所有子元素,转成list避免遍历过程中结构变化 for child in list(node.children): if isinstance(child, NavigableString): child.replace_with("") else: clear_all_text(child) clear_all_text(soup) print(minify(str(soup)))
这两种写法都能把所有文本(包括那个“4”)清掉,只保留HTML的标签和属性结构。
内容的提问来源于stack exchange,提问作者chhenning
相关产品推荐
相关产品推荐

