如何从.NET 6 MVC的CSHTML文件提取静态文本内容?
提取.NET 6 MVC项目CSHTML中的静态文本(排除动态内容)
需求背景
需要从.NET 6 MVC的CSHTML视图文件中批量提取静态文本(按钮文本、标题、span内容、属性内的静态文本等),排除数据库/API返回的动态内容(如data-bind绑定值、ViewBag/Razor动态表达式渲染内容),用于多语言翻译的手动处理。
方案1:自定义C#控制台程序(推荐)
利用HtmlAgilityPack解析HTML内容,配合文本预处理过滤Razor动态代码,精准提取静态文本。
步骤1:安装依赖
在控制台项目中安装NuGet包:
Install-Package HtmlAgilityPack
步骤2:核心代码实现
using HtmlAgilityPack; using System.Text.RegularExpressions; class CsHtmlStaticTextExtractor { static void Main(string[] args) { // 替换为你的CSHTML文件根目录 string rootDir = @"C:\YourMvcProject\Views"; var allStaticTexts = new HashSet<string>(); // 自动去重 // 遍历所有.cshtml文件 foreach (var file in Directory.EnumerateFiles(rootDir, "*.cshtml", SearchOption.AllDirectories)) { string content = File.ReadAllText(file); var texts = ExtractStaticTextsFromCsHtml(content); foreach (var text in texts) { if (!string.IsNullOrWhiteSpace(text)) { allStaticTexts.Add(text.Trim()); } } } // 输出结果到文件 File.WriteAllLines("StaticTexts.txt", allStaticTexts.OrderBy(t => t)); Console.WriteLine($"提取完成,共{allStaticTexts.Count}条静态文本"); } static IEnumerable<string> ExtractStaticTextsFromCsHtml(string csHtmlContent) { // 1. 预处理:移除Razor代码块中的动态逻辑,保留块内HTML内容 string processedContent = Regex.Replace(csHtmlContent, @"@\s*(if|else|foreach|for|while)\s*\([^)]*\)\s*\{\s*", "", RegexOptions.Singleline); processedContent = Regex.Replace(processedContent, @"}\s*else\s*\{\s*", "", RegexOptions.Singleline); processedContent = Regex.Replace(processedContent, @"}\s*", "", RegexOptions.Singleline); // 2. 移除Razor动态表达式(如@ViewBag.xxx、@Model.xxx) processedContent = Regex.Replace(processedContent, @"@\s*(\w+\.)+\w+", "", RegexOptions.Singleline); // 3. 使用HtmlAgilityPack解析HTML var doc = new HtmlDocument(); doc.LoadHtml(processedContent); // 4. 提取文本节点,排除data-bind元素的空占位文本,保留静态fallback内容 var textNodes = doc.DocumentNode.SelectNodes("//text()")?.Where(node => { var parent = node.ParentNode; if (parent.Attributes["data-bind"] != null) { return !string.IsNullOrWhiteSpace(node.InnerText.Trim()); } return true; }); if (textNodes != null) { foreach (var node in textNodes) { var parts = node.InnerText.Split(new[] { '\n', '\r', '\t', '<', '>' }, StringSplitOptions.RemoveEmptyEntries); foreach (var part in parts) { var trimmed = part.Trim(); if (!string.IsNullOrWhiteSpace(trimmed)) { yield return trimmed; } } } } // 5. 提取data-content等属性内的HTML文本 var attrNodes = doc.DocumentNode.SelectNodes("//@*[contains(name(), 'data-')]")?.Where(attr => { return attr.Value.Contains("<div") || attr.Value.Contains("<span"); }); if (attrNodes != null) { foreach (var attr in attrNodes) { var innerDoc = new HtmlDocument(); innerDoc.LoadHtml(attr.Value); var innerTexts = innerDoc.DocumentNode.SelectNodes("//text()"); if (innerTexts != null) { foreach (var innerText in innerTexts) { var trimmed = innerText.InnerText.Trim(); if (!string.IsNullOrWhiteSpace(trimmed)) { yield return trimmed; } } } } } } }
代码说明
- 预处理阶段过滤Razor动态代码块和表达式,仅保留HTML结构与静态文本
- 针对
data-bind元素,保留其内部的静态fallback文本(如示例中的FirstText1、LASTTEXT) - 解析
data-content等属性内的嵌套HTML,提取其中的静态文本 - 自动去重并输出有序的静态文本列表
方案2:正则表达式快速提取(适合临时需求)
若无需复杂HTML解析,可使用正则快速提取静态文本,准确性略低于HtmlAgilityPack方案:
using System.Text.RegularExpressions; class QuickExtractor { static void Main(string[] args) { string rootDir = @"C:\YourMvcProject\Views"; var allTexts = new HashSet<string>(); foreach (var file in Directory.EnumerateFiles(rootDir, "*.cshtml", SearchOption.AllDirectories)) { string content = File.ReadAllText(file); // 提取HTML标签内的静态文本 var tagTexts = Regex.Matches(content, @"<[^>]+>([^<]+)</[^>]+>", RegexOptions.Singleline) .Cast<Match>() .Select(m => m.Groups[1].Value.Trim()) .Where(t => !string.IsNullOrWhiteSpace(t) && !t.Contains("@") && !t.Contains("data-bind")); // 提取data-content属性内的文本片段 var attrTexts = Regex.Matches(content, @"data-content=""[^""]+""", RegexOptions.Singleline) .Cast<Match>() .Select(m => Regex.Replace(m.Value, @"data-content=""|<[^>]+>|""", "").Trim()) .SelectMany(t => t.Split(new[] { '.', '?', '!' }, StringSplitOptions.RemoveEmptyEntries)) .Select(t => t.Trim()) .Where(t => !string.IsNullOrWhiteSpace(t)); foreach (var text in tagTexts.Concat(attrTexts)) { allTexts.Add(text); } } File.WriteAllLines("QuickStaticTexts.txt", allTexts.OrderBy(t => t)); } }
注意事项
- 若需要提取
@("静态文本")这类Razor静态字符串,可修改预处理逻辑,保留@("...")内的字符串内容 - 复杂嵌套HTML场景下,
HtmlAgilityPack方案的准确性远高于正则 - 可根据项目实际情况调整正则或HTML选择器,比如添加更多需要排除的动态属性(如
asp-for等)
内容的提问来源于stack exchange,提问作者Nagaajay k
相关产品推荐
相关产品推荐

