C#读取文件过滤数字特殊字符后存入Hashtable统计词频实现问题
解决方案
核心思路是直接用正则表达式从文本中提取所有符合「纯小写字母组成」规则的单词,跳过拆分后过滤的步骤,适配任意数量特殊字符、数字的文件场景,同时修复原有代码的逻辑错误。
原有代码的核心问题
- 正则表达式语法错误:
@"^[a - z] +$"里的空格是多余的,会匹配字符间带空格的内容,完全不符合预期 - 逻辑错误:判断哈希表是否存在键时错误使用了
words[0],输出词频时误用了hashT[words]整体数组作为键 - 没有释放文件读取资源,容易出现文件占用异常
修正后的实现代码
using System; using System.Collections; using System.IO; using System.Text.RegularExpressions; namespace ConsoleApp1 { class Program { static void Main(string[] args) { Hashtable hashT = new Hashtable(); // 用using自动释放StreamReader资源,避免文件锁定 using (TextReader tr = new StreamReader(@"C:\file including numbers and spacial charecters.txt")) { string myLine; // 匹配纯小写字母组成的完整单词的正则,提前编译提升多文件处理性能 Regex pureLowerWordRegex = new Regex(@"\b[a-z]+\b", RegexOptions.Compiled); while ((myLine = tr.ReadLine()) != null) { // 直接提取当前行所有符合要求的单词,自动过滤数字、特殊字符 MatchCollection matches = pureLowerWordRegex.Matches(myLine); foreach (Match match in matches) { string word = match.Value; if (hashT.ContainsKey(word)) { // 词频直接用整数存储即可,不需要double类型 hashT[word] = (int)hashT[word] + 1; } else { hashT.Add(word, 1); } } } } // 所有内容读取完成后统一输出词频结果 foreach (string word in hashT.Keys) { Console.WriteLine($"{word} {hashT[word]}"); } Console.ReadKey(); } } }
补充说明
正则\b[a-z]+\b中,\b代表单词边界,避免匹配到长字符串中间的小写字母片段;[a-z]+匹配1个及以上的小写字母,不需要提前对文本做拆分处理,不管文件里有多少种特殊字符、数字都可以自动过滤。
如果需要兼容大写字母的场景,可以给正则加上RegexOptions.IgnoreCase参数,或者将匹配到的单词统一转小写后再存入哈希表即可。
内容的提问来源于stack exchange,提问作者TakToJa
相关产品推荐
相关产品推荐

