因为 string.split 默认保留分隔符之外的所有字符,而换行符在 windows 环境下是 \r\n(回车+换行),如果只按 \n 拆分,\r 就会残留在每行的末尾。要彻底清除这些字符,应在调用 split 时传入 stringsplitoptions.removeemptyentries 并配合 trimend,或者直接使用 environment.newline 作为分隔符进行拆分。

为什么 Split('\n') 会留下 \r?
因为在 Windows 系统中,文本文件的换行序列由两个字符组成:回车符 \r (ASCII 13) 和换行符 \n (ASCII 10)。当使用 Split(new char[] { '\n' }) 时,字符串仅会在 \n 处断开,前面的 \r 被视为普通字符被保留在结果数组的每个元素末尾。这导致后续处理如比较或写入文件时出现意外匹配失败或格式错误。

string text = "Line1\r\nLine2\r\nLine3";
string[] lines = text.Split(new char[] { '\n' });
foreach (var line in lines)
{
Console.WriteLine($"[{line}] Length: {line.Length}");
}预期输出:
[Line1 ] Length: 6
[Line2 ] Length: 6
[Line3 ] Length: 6
注意方括号内的 代表不可见的 \r 字符。
如何正确拆分并清理空白字符?
最可靠的方法是使用 StringSplitOptions.RemoveEmptyEntries 结合 Trim() 或 TrimEnd(),或者直接按 Environment.NewLine 拆分。推荐使用 Split 的多字符重载或正则表达式来处理混合换行情况。以下代码展示了标准做法,确保每行内容纯净无尾部控制字符。

string text = "Line1\r\nLine2\r\nLine3";
// 方法1:按新行符拆分并移除空项
string[] cleanLines1 = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
// 方法2:按 \n 拆分后手动 TrimEnd
string[] cleanLines2 = text.Split(new char[] { '\n' })
.Select(s => s.TrimEnd('\r'))
.ToArray();
foreach (var line in cleanLines1)
{
Console.WriteLine($"[{line}] Length: {line.Length}");
}预期输出:
[Line1] Length: 5
[Line2] Length: 5
[Line3] Length: 5
此时每行长度均为实际字符数,无残留控制符。
如果输入中包含混合换行符(\r\n 和 \n)怎么办?
当输入数据来自不同平台(如 Linux 生成的 \n 和 Windows 生成的 \r\n)时,单一分隔符无法统一处理。此时应使用 Regex.Split 按 \r?\n 模式拆分,或先统一替换换行符再拆分。这种方法能兼容所有常见换行格式,确保解析结果的一致性。


















