在C#中规范换行符
时间:2020-03-06 14:47:49 来源:igfitidea点击:
我有一个数据流,其中可能包含\ r,\ n,\ r \ n,\ n \ r或者它们的任意组合。是否有一种简单的方法来规范化数据以使它们全部变成\ r \ n对以使显示更加一致?
因此,将产生这种转换表:
\r --> \r\n \n --> \r\n \n\n --> \r\n\r\n \n\r --> \r\n \r\n --> \r\n \r\n\n --> \r\n\r\n
解决方案
一个正则表达式可以帮助..可以做大致这样的事情..
(\ r \ n | \ n \ n | \ n \ r | \ r | \ n)替换为\ r \ n
此正则表达式从发布的表中生成了这些结果(仅测试左侧),因此替换应归一化。
\r => \r \n => \n \n\n => \n\n \n\r => \n\r \r\n => \r\n \r\n => \r\n \n => \n
我们觉得太复杂了。
忽略每个\ r并将每个\ n转换为\ r \ n。
在伪C#中:
char[] chunk = new char[X]; StringBuffer output = new StringBuffer(); buffer.Read(chunk); foreach (char c in chunk) { switch (c) { case '\r' : break; // ignore case '\n' : output.Append("\r\n"); default : output.Append(c); } }
编辑:\ r本身不是行终止符,所以我怀疑我们是否真的想将\ r扩展为\ r \ n。
我相信这将满足需求:
using System.Text.RegularExpressions; // ... string normalized = Regex.Replace(originalString, @"\r\n|\n\r|\n|\r", "\r\n");
我不确定100%的确切语法,也没有方便检查的.Net编译器。我用perl编写了它,然后将其转换为(希望是正确的)C#。唯一真正的技巧是首先匹配" \ r \ n"和" \ n \ r"。
要将其应用于整个流,只需在大块输入上运行即可。 (如果需要,可以使用流包装器执行此操作。)
原始的perl:
$str =~ s/\r\n|\n\r|\n|\r/\r\n/g;
测试结果:
[bash$] ./test.pl \r -> \r\n \n -> \r\n \n\n -> \r\n\r\n \n\r -> \r\n \r\n -> \r\n \r\n\n -> \r\n\r\n
更新:现在将\ n \ r转换为\ r \ n,尽管我不称其为标准化。
我在RegEx上与Jamie Zawinski在一起:
"有些人遇到问题时会想:"我知道,我会使用正则表达式。"现在他们有两个问题。"
对于那些喜欢可读性的人:
- 第1步将\ r \ n替换为\ n将\ n \ r替换为\ n(如果我们确实希望这样做,某些张贴者似乎不认为)将\ r替换为\ n
- 步骤2将\ n替换为Environment.NewLine或者\ r \ n或者其他名称。
我同意正则表达式是答案,但是其他所有人都没有提到Unicode行分隔符。这些(及其与\ n的变化)应包括在内。