不能直接用\s+替换所有空白,因会破坏内联样式、script字符串及ASI分号插入边界;需区分HTML结构空白与嵌入内容空白;删注释须用[\s\S]*?实现跨行非贪婪匹配。

为什么不能直接用 \s+ 替换所有空白
盲目把所有空白字符(包括换行、制表符、空格)替换成单个空格,会破坏内联样式或 script 中的字符串内容。比如 style="white-space: pre;" 或 console.log("a\nb") 里的换行是语义性的,删掉就出错。
更危险的是,\s+ 会把 <script></script> 标签内的空白也一并压缩,而 JS 引擎对某些换行敏感(如 ASI 自动分号插入边界)。
所以必须区分“HTML 结构空白”和“嵌入内容空白”。
删除 HTML 注释的正则必须带 [\s\S]*?
标准注释 <!-- ... --> 可能跨多行,普通 .* 在单行模式下无法匹配换行符。
正确写法是:<!--[\s\S]*?--> ——其中 [\s\S] 表示“任意字符(含换行)”,*? 是非贪婪匹配,避免误吞多个注释之间的正常标签。
常见错误:<!--.*--> 在 VS Code 或 sed 中默认不跨行,结果只删掉第一行;<!--(.|\n)*--> 效率低且部分引擎不支持 \n 在字符组里。
> 和 之间空白要单独清理
浏览器忽略标签间的空白,但 <div>\n <p>text</p>
<p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill6712" title="Wechat HTML Publisher"><img
src="https://img.php.cn/upload/skill/000/000/081/179109368394970.jpg" alt="Wechat HTML Publisher" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill6712" title="Wechat HTML Publisher">Wechat HTML Publisher</a>
<p>直接上传HTML富文本到微信公众号草稿箱。支持完整的HTML格式,无需Markdown转换。</p>
</div>
<a href="/xiazai/skill6712" title="Wechat HTML Publisher" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div>\n</div> 压缩后若变成 <div>
<p>text</p>
<p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p>
</div> 才真正节省体积;如果只删换行不处理 > 后的空格,会残留 >
推荐两步走:
- 先用
>\s+ 替换为 <code>(注意:必须确保中间没 JS 字符串含 <code>>或) - 再用
\s+替换为单空格,最后.trim()
<script>if(a>b){...}</script>,这一步就得跳过或手动保护。PHP / Node.js 脚本里注释清理容易漏掉条件注释
旧项目可能还留着 IE 条件注释,比如:<!--[if IE]><link...<![endif]-->。
这种不是标准 HTML 注释,<!--[\s\S]*?--> 会把它整个干掉,导致 IE 用户丢失样式。
如果你确定已放弃 IE 支持,就放心删;否则得加白名单逻辑,或者用专门解析器(如 html-minifier-terser 的 ignoreCustomFragments 选项)。
另一个坑:有些构建工具(如 Vite 插件)默认不处理


















