Visual Studio 2022提取项目新词存SQL Server字典表及Regex适配咨询
完全可以用Regex类实现你的需求,你贴的微软示例也能适配,只是需要把原有的“匹配重复单词”逻辑改成“提取目标新词”的逻辑。下面是具体的实现建议和适配方案:
一、整体实现流程
- 遍历Visual Studio项目目录下的目标文件(
.cs、.js、.html) - 读取每个文件的文本内容
- 用Regex提取符合你定义的“新词”规则的词汇
- 对比SQL Server字典表,过滤已存在的词汇
- 将新词批量插入字典表
二、Regex的适配与调整
你提供的示例是用来匹配重复单词的,要改成提取目标词汇,核心是替换正则表达式,同时复用原示例的Regex.Matches和遍历匹配结果的逻辑:
1. 不同文件类型的词汇提取正则
首先得明确你的“新词”定义(比如业务术语、自定义标识符、非标准HTML标签等),以下是针对不同文件类型的通用正则参考:
- C#文件:提取类名、方法名等自定义标识符(过滤系统关键字)
// 匹配PascalCase、camelCase格式的标识符 Regex rxCSharp = new Regex(@"([A-Z][a-z0-9]+)+|([a-z][a-z0-9]*[A-Z][a-z0-9]+)*", RegexOptions.Compiled); - JavaScript文件:提取变量名、函数名(支持下划线命名)
Regex rxJs = new Regex(@"([A-Z][a-z0-9]+)+|([a-z][a-z0-9_]*[A-Z][a-z0-9_]+)*|[_a-z][a-z0-9_]*", RegexOptions.Compiled); - HTML文件:提取自定义标签、属性名和文本中的业务词汇
Regex rxHtml = new Regex(@"<([a-z0-9-]+)|([a-z0-9-]+)=|\b([A-Za-z][A-Za-z0-9-]+)\b", RegexOptions.Compiled | RegexOptions.IgnoreCase);
2. 适配原示例的完整代码
把原示例的重复词匹配逻辑替换成新词提取+入库的逻辑,示例代码如下:
using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; using System.Data.SqlClient; using System.Linq; public class DictionaryUpdater { public static void Run(string projectRootPath) { // 定义要处理的文件扩展名 string[] targetExtensions = { ".cs", ".js", ".html" }; // 遍历项目下所有目标文件 var targetFiles = Directory.EnumerateFiles(projectRootPath, "*.*", SearchOption.AllDirectories) .Where(file => targetExtensions.Contains(Path.GetExtension(file).ToLower())); // 按文件类型映射对应的正则 var regexMap = new Dictionary<string, Regex> { { ".cs", new Regex(@"([A-Z][a-z0-9]+)+|([a-z][a-z0-9]*[A-Z][a-z0-9]+)*", RegexOptions.Compiled) }, { ".js", new Regex(@"([A-Z][a-z0-9]+)+|([a-z][a-z0-9_]*[A-Z][a-z0-9_]+)*|[_a-z][a-z0-9_]*", RegexOptions.Compiled) }, { ".html", new Regex(@"<([a-z0-9-]+)|([a-z0-9-]+)=|\b([A-Za-z][A-Za-z0-9-]+)\b", RegexOptions.Compiled | RegexOptions.IgnoreCase) } }; // 从数据库读取已存在的词汇,避免重复插入 var existingWords = GetExistingWordsFromDb(); var newWords = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (var file in targetFiles) { string fileContent = File.ReadAllText(file, System.Text.Encoding.UTF8); string ext = Path.GetExtension(file).ToLower(); if (regexMap.TryGetValue(ext, out Regex rx)) { MatchCollection matches = rx.Matches(fileContent); foreach (Match match in matches) { string word = match.Value.Trim(); // 过滤空字符串、短词和已存在的词 if (!string.IsNullOrEmpty(word) && word.Length > 1 && !existingWords.Contains(word)) { newWords.Add(word); } } } } // 批量插入新词到数据库 InsertNewWordsToDb(newWords); Console.WriteLine($"共新增 {newWords.Count} 个词汇到字典表"); } // 从SQL Server字典表读取已存在的词汇 private static HashSet<string> GetExistingWordsFromDb() { var words = new HashSet<string>(StringComparer.OrdinalIgnoreCase); // 替换成你的数据库连接字符串 string connString = "Server=你的服务器名;Database=你的数据库名;User Id=账号;Password=密码;"; using (SqlConnection conn = new SqlConnection(connString)) { conn.Open(); string query = "SELECT Word FROM 你的字典表名"; using (SqlCommand cmd = new SqlCommand(query, conn)) { using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { words.Add(reader.GetString(0)); } } } } return words; } // 批量插入新词到字典表 private static void InsertNewWordsToDb(HashSet<string> newWords) { if (newWords.Count == 0) return; string connString = "Server=你的服务器名;Database=你的数据库名;User Id=账号;Password=密码;"; using (SqlConnection conn = new SqlConnection(connString)) { conn.Open(); string insertSql = "INSERT INTO 你的字典表名 (Word) VALUES (@Word)"; using (SqlCommand cmd = new SqlCommand(insertSql, conn)) { cmd.Parameters.Add("@Word", System.Data.SqlDbType.NVarChar); foreach (string word in newWords) { cmd.Parameters["@Word"].Value = word; cmd.ExecuteNonQuery(); } } } } }
三、关键注意事项
- 过滤系统关键字:可以维护一个排除词列表(比如C#的
class、void,HTML的div、span),在添加新词时过滤这些内容。 - 性能优化:用
HashSet存储词汇避免重复,RegexOptions.Compiled编译正则提升匹配速度,大量文件时可以考虑异步读取。 - 编码问题:读取文件时指定正确的编码(比如UTF-8),避免乱码导致匹配失败。
- 数据库安全:必须使用参数化查询防止SQL注入,大量新词时用
SqlBulkCopy批量插入效率更高。 - VS集成:可以把这段代码做成控制台项目,直接在VS里运行;如果需要更便捷的触发方式,还可以借助VS SDK做一个自定义工具菜单。
四、原示例的适配说明
你贴的微软示例核心逻辑是用Regex.Matches提取匹配内容,然后遍历处理结果,这个逻辑完全可以复用。只需要把原示例中“匹配重复词”的正则替换成你需要的“提取新词”的正则,再把输出逻辑改成“收集新词+入库”即可,原示例的RegexOptions.Compiled和遍历MatchCollection的写法都可以直接沿用。
内容的提问来源于stack exchange,提问作者Djydan
相关产品推荐
相关产品推荐

