应优先使用htmlagilitypack等专业解析器而非正则,因正则无法正确处理html嵌套、注释、cdata、转义及大小写不敏感等问题;仅在完全可控的单层纯文本场景才可谨慎使用正则分步清理。

直接用 Regex.Replace 配合简单正则就能快速去标签,但别 blindly 用 <.></.> —— 它在嵌套、注释、CDATA 或含换行的标签里会崩,实际项目中大概率出错。
为什么 <.></.> 在 C# 里不安全
这个模式看似“非贪婪”,但遇到 <script>console.log('<div>');</script> 这类内容时,会把整个 <script>...</script> 当成一个标签切掉,而实际只想删标签、保留脚本里的文本。更糟的是,它完全不处理 HTML 注释(<!-- ... -->)、CDATA()或自闭合标签(<br>)的边界问题。
常见错误现象:Regex.Replace(html, "<.>", "")</.> 把一段含引号属性的 <a href="x>y"></a> 切成碎片,或漏掉多行 <style></style> 块。
- 它不区分开始/结束标签,也不跳过注释和 CDATA 区域
- 没设
RegexOptions.Singleline时,.不匹配换行符,导致跨行标签失效 - 对
等实体不做还原,输出里全是乱码符号
Regex.Replace 分步清理比单次匹配更可靠
真正能落地的方案是分层清除:先干掉危险块(<script></script>、<style></style>、注释),再清普通标签,最后规整空白和实体。顺序不能乱,否则 <script></script> 里的 <div> 可能被误删。<p>实操建议:</p>
<ul>
<li>用 <code>@"<script>]*?>[\s\S]*?</script>" 和 @"<style>]*?>[\s\S]*?</style>" 清除脚本与样式块([\s\S] 确保跨行)
@"<!--[\s\S]*?-->" 清除注释(注意开头的 !)@"]*>" 清普通标签(比 <.></.> 更明确,[^>] 避免误吞内容)Regex.Unescape 或手动替换常见实体,比如 → 空格、< →
示例片段:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
string CleanHtml(string html)
{
if (string.IsNullOrEmpty(html)) return html;
html = Regex.Replace(html, @"<script>]*?>[\s\S]*?</script>", "", RegexOptions.IgnoreCase);
html = Regex.Replace(html, @"<style>]*?>[\s\S]*?</style>", "", RegexOptions.IgnoreCase);
html = Regex.Replace(html, @"<!--[\s\S]*?-->", "", RegexOptions.IgnoreCase);
html = Regex.Replace(html, @"]*>", "");
html = Regex.Replace(html, @" ", " ", RegexOptions.IgnoreCase);
html = Regex.Replace(html, @"&(quot|amp|lt|gt);", m => m.Groups[1].Value switch
{
"quot" => "\"",
"amp" => "&",
"lt" => " ">",
_ => ""
});
return Regex.Replace(html, @"\s+", " ").Trim();
}
什么时候该放弃正则,改用 HtmlAgilityPack
如果你要处理的是完整 HTML 文档(比如从富文本编辑器存入 DB 的内容),或者需要保留某些标签(如只删 <script></script> 但留 <p></p> 和 <strong></strong>),正则就力不从心了。
典型场景:
- HTML 结构不规范(缺失闭合标签、大小写混用、属性值无引号)
- 需提取特定节点文本(如只取
<article></article>内容) - 导出 Excel 时要求段落换行、列表缩进等语义还原
这时直接上 HtmlAgilityPack 更稳:
var doc = new HtmlDocument(); doc.LoadHtml(html); string text = doc.DocumentNode.InnerText;
它自动解析 DOM、修复嵌套、忽略注释和 CDATA,且不依赖正则回溯逻辑 —— 对复杂 HTML 的鲁棒性远高于手写正则。
真正容易被忽略的点是:多数业务场景根本不需要“完美还原语义”,但开发者常高估输入 HTML 的质量。先跑一遍 ]*> + 实体处理,90% 的摘要、日志、导出需求就已覆盖;只有当测试发现大量 <div> 残留或换行错乱时,才值得引入 HtmlAgilityPack —— 不要一开始就把简单问题工程化。</div>










