在富文本编辑、网页爬虫清洗、后端接口返回内容过滤等场景中,经常需要对一段 HTML 字符串做局部删除,比如移除所有带特定类名的 <div> 容器。直接对字符串使用 replace 或正则看似简单,但因为 HTML 的嵌套结构和标签属性复杂度,很容易出现删不干净、误删兄弟节点、破坏标签闭合等问题。更合理的方式是把字符串交给浏览器的 HTML 解析器,在 DOM 树上定位并移除节点,再把树序列化回字符串。这个过程既能保证结构完整,又能利用标准选择器精确命中目标。

一、为什么正则移除 <div> 很危险
很多人第一反应是使用 JavaScript 的正则表达式,例如匹配 <div> 开标签到 </div> 闭标签之间的所有内容。这个思路在标签不会嵌套、属性固定且没有注释干扰时勉强可用,但实际内容几乎不会这么理想。HTML 允许 <div> 内部继续嵌套其他 <div>,也允许属性值里包含 > 这样的字符,甚至注释中可能写有看似标签的文本。正则表达式本质上是处理正则语言,而 HTML 是上下文相关文法,嵌套结构无法用一条简单的正则可靠描述。
假设有一段 HTML 字符串包含两层 <div>。使用一个贪婪或非贪婪的正则去匹配闭标签,通常会提前在第一个 </div> 处结束,导致内层结构没有被完整移除,或者把外层标签的闭合部分截断。比如 /<div[^>]*>[sS]*?</div>/gi 这种写法,遇到嵌套时就无法正确处理。更糟的是,如果属性中包含 >,开标签的匹配也可能提前终止。下面这段代码表面上看能删除 div,实际很容易出错:
// 危险的字符串替换方式 const html = '<div class="box">外层<div>内层</div></div>'; const result = html.replace(/<div[^>]*>[sS]*?</div>/gi, ''); console.log(result); // 很可能剩下残缺的闭合标签
除了嵌套问题,HTML 注释、<script> 或 <style> 区块中的文本也可能含有类似标签的字符串,正则很难区分代码块和真实节点。即使不断补丁正则,也无法覆盖所有边界条件,后期维护成本极高。因此,只要浏览器环境可用,应当优先使用 DOM 解析方案。
二、用 DOMParser 安全解析并移除节点
浏览器原生提供了 DOMParser 接口,可以将完整的 HTML 字符串解析为一个独立的文档对象。通过 parseFromString 方法指定 text/html 类型,就能获得一个不会渲染、不会执行脚本的 Document。这个解析过程由浏览器底层 HTML 解析器完成,它会自动修正不完整的标签、处理嵌套关系、忽略无效的闭合标签,和真实页面加载时的解析规则基本一致。
解析之后,我们需要在文档中查找目标 <div> 元素。可以使用 querySelectorAll 传入 CSS 选择器,例如选择所有类名为 remove-me 的 div,或者通过 data-role 属性定位。找到的是一个 NodeList,在遍历删除时要注意列表长度会动态变化:如果正向遍历时直接调用 <