在 .NET C# 中处理用户输入或第三方 HTML 内容时,常需要去掉不需要的标签或属性(如 <script>、style、class、onclick 等),防止 XSS 或样式污染。使用正则表达式是一种简洁快速的方式,适合处理简单结构或已知标签类型的 HTML 内容。
移除所有 HTML 标签的基本正则
最常用的方式是:
string result = Regex.Replace(htmlString, "<.*?>", String.Empty);
或使用编译模式提高性能:
static Regex _htmlRegex = new Regex("<.*?>", RegexOptions.Compiled);
string result = _htmlRegex.Replace(htmlString, "");
这种方法适合将所有标签一次性剥离,只保留纯文本内容。
删除 <script>、<style> 及其内容
要彻底过滤 CSS 和 JS,还应先删除这些标签及其内部内容:
html = Regex.Replace(html, "<script[^>]*?>[\\s\\S]*?<\\/script>", "");
html = Regex.Replace(html, "<style[^>]*?>[\\s\\S]*?<\\/style>", "");
html = Regex.Replace(html, "<.*?>", "");
这一步可规避用户注入脚本或样式标签带来的风险。
筛选保留特定标签,移除其属性
某些场景下需要保留标签,但过滤它们的属性,例如保留 <a> 标签的文本内容,但清除 href、class 属性。可以使用如下正则:
string cleaned = Regex.Replace(html, @"<(\/?\w+)(?:\s+[\w-]+=([""'])?.*?\1?>", "<$1>");
或针对特定属性(如 class 或 style)进行独立替换:
var pattern = @"\s*(style|class)=(['""]).*?\2";
cleaned = Regex.Replace(html, pattern, "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
这种方法适合过滤不受信任属性,同时保留结构标签。
匹配指定标签且含特定属性的用法
例如,你要捕获 <img> 中带有 src="goal.gif" 的标签,可用:
<img[^>]+goal\.gif.*?>
其中 [^>]+ 确保匹配中途不跨标签边界。
或者按顺序捕获 <div> 标签中某些属性的值:
<div\b(?>\s+(?:id="([^"]*)"|class="([^"]*)")|[^\s>]+|\s+)*>
该正则可同时捕获 id 和 class 不论顺序如何出现。
注意事项与推荐最佳实践
不适用正则解析复杂 HTML:HTML 是上下文敏感语言,嵌套标签、注释和 CDATA 块可能导致正则无法正确处理。不建议用于完整 HTML DOM 解析。
对于复杂结构推荐使用 HTML Agility Pack 或 AngleSharp:这些专用库能安全解析 HTML 文档结构,兼容不规范标签,并支持更精细操控,如提取链接、过滤属性、清理脚本等。
过滤属性时留意属性名的多样性:属性名可能包含 -,例如 data-id 或 data-columns,相应的正则要考虑 [\w-]+=".*?" 模式才能匹配完整属性名。
综合示例:C# 方法实现
public static string StripHtml(string input) {
if (string.IsNullOrEmpty(input)) return string.Empty;
// 删除 script/style 标签及内容
input = Regex.Replace(input, "<script[^>]*?>[\\s\\S]*?<\\/script>", "", RegexOptions.IgnoreCase);
input = Regex.Replace(input, "<style[^>]*?>[\\s\\S]*?<\\/style>", "", RegexOptions.IgnoreCase);
// 移除所有 HTML 标签
input = Regex.Replace(input, "<.*?>", "", RegexOptions.Compiled);
return input;
}
public static string RemoveAttributes(string html, params string[] attrs) {
foreach (var attr in attrs) {
string pattern = $@"\s*{attr}=(['""]).*?\1";
html = Regex.Replace(html, pattern, "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
}
return html;
}
第一个方法彻底提取纯内容;第二个方法可用于清除特定属性,如 "class"、"style" 或 "onclick"。
总结
- 使用 <.*?> 正则快速去标签,适用于简单情况。
- 若需要更安全全面、更兼容复杂结构,推荐采用 HTML Agility Pack 或 AngleSharp 之类的解析器。
- 属性过滤可通过正则单独移除特定属性,但要处理属性命名多元化。
- 正则虽便捷高效,但有局限,需根据具体场景审慎使用。
通过上述方法和说明,你可以在 .NET C# 中灵活控制 HTML 输出,达到既安全又可控的文本处理效果。