如何在C#中Split字符串时保留分隔符,提取带标点的完整句子?
解决方法:保留标点分割句子
你的现有代码问题在于用Split按标点分割时,会把.?!这些标点直接丢弃,所以输出的句子没有结尾符号。这里给你两种简单的实现方式:
方法一:正则表达式(简洁高效)
用正则的正向零宽断言可以在分割时保留标点,代码如下:
string data = System.IO.File.ReadAllText(filePath); // 按「标点+空白」的位置分割,保留标点 string[] sentences = System.Text.RegularExpressions.Regex.Split(data, @"(?<=[.!?])\s+"); // 过滤掉可能的空字符串(比如文件首尾的空白) sentences = sentences.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); foreach (string s in sentences) { Console.WriteLine(s); }
通俗解释正则逻辑
这个正则的核心是找「分割的位置」而非「要切掉的字符」:
(?<=[.!?]):相当于“回头看一眼”,确认当前位置的前面是.、!、?中的一个标点\s+:表示这里有一个或多个空白(空格、换行、制表符都算)- 合起来就是:在「标点后面跟着空白」的地方切一刀,但切的时候不会把前面的标点切掉——就像你切面包,在果酱和面包的缝隙切,果酱还留在面包片上。这样分割出来的每一段自然就带着结尾的标点了。
方法二:手动遍历拼接(直观可控)
如果不想用正则,也可以手动遍历字符拼接句子,适合需要处理特殊情况(比如缩写里的.)的场景:
string data = System.IO.File.ReadAllText(filePath); List<string> sentences = new List<string>(); StringBuilder currentSentence = new StringBuilder(); foreach (char c in data) { currentSentence.Append(c); // 遇到句子结尾标点时,保存当前句子并重置 if (c == '.' || c == '!' || c == '?') { sentences.Add(currentSentence.ToString().Trim()); currentSentence.Clear(); } } // 处理文件最后一段没有结尾标点的内容 if (currentSentence.Length > 0) { sentences.Add(currentSentence.ToString().Trim()); } foreach (string s in sentences) { Console.WriteLine(s); }
注意:这个基础版本会把Mr.这类缩写误判为句子结尾,如果你需要处理这类情况,可以加额外判断(比如检查标点前的单词是不是常见缩写)。
内容的提问来源于stack exchange,提问作者kendall.tubbs
相关产品推荐
相关产品推荐

