在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的变化)应包括在内。