什么是在C#/ .NET中强制使用CRLF的快速方法?

你将如何规范化一个string中的所有新行序列为一种types?

我正在寻求使他们所有的电子邮件(MIME文件)的CRLF。 理想情况下,这将被包装在一个静态方法,执行速度非常快,而不是使用正则expression式(因为换行符,回车等方面的差异是有限的)。 也许甚至有一个我忽略的BCL方法?

假设:在给了这个更多的思考之后,我认为这是一个安全的假设,认为CR是单独的或者是CRLF序列的一部分。 也就是说,如果你看到CRLF,那么你知道所有的CR都可以被删除。 否则,很难判断应该从“\ r \ n \ n \ r”这样的东西出来多less行。

input.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", "\r\n") 

如果input只包含一种换行符 – CR,LF或CR + LF,这将起作用。

这取决于需求是什么。 特别是,你想怎么处理“\ r”呢? 如果这算作是一个换行符? 作为一个例子,如何处理“a \ n \ rb”? 这是一个非常奇怪的换行符,一个“\ n”突破,然后一个stream氓“\ r”,或两个单独的换行符? 如果“\ r”和“\ n”都可以自行换行,为什么“\ r \ n”不能被当作两个换行符呢?

这里有一些代码,我怀疑是相当有效的。

 using System; using System.Text; class LineBreaks { static void Main() { Test("a\nb"); Test("a\nb\r\nc"); Test("a\r\nb\r\nc"); Test("a\rb\nc"); Test("a\r"); Test("a\n"); Test("a\r\n"); } static void Test(string input) { string normalized = NormalizeLineBreaks(input); string debug = normalized.Replace("\r", "\\r") .Replace("\n", "\\n"); Console.WriteLine(debug); } static string NormalizeLineBreaks(string input) { // Allow 10% as a rough guess of how much the string may grow. // If we're wrong we'll either waste space or have extra copies - // it will still work StringBuilder builder = new StringBuilder((int) (input.Length * 1.1)); bool lastWasCR = false; foreach (char c in input) { if (lastWasCR) { lastWasCR = false; if (c == '\n') { continue; // Already written \r\n } } switch (c) { case '\r': builder.Append("\r\n"); lastWasCR = true; break; case '\n': builder.Append("\r\n"); break; default: builder.Append(c); break; } } return builder.ToString(); } } 
 string nonNormalized = "\r\n\n\r"; string normalized = nonNormalized.Replace("\r", "\n").Replace("\n", "\r\n"); 

简单的变体:

 Regex.Replace(input, @"\r\n|\r|\n", "\r\n") 

为了更好的performance:

 static Regex newline_pattern = new Regex(@"\r\n|\r|\n", RegexOptions.Compiled); [...] newline_pattern.Replace(input, "\r\n"); 

我的意思是,这是一个快速的方法。

它不使用昂贵的正则expression式函数。 它也不使用多个replace函数,每个replace函数都通过多个检查,分配等循环遍历数据。

所以search直接在1 for循环中完成。 对于结果数组容量必须增加的次数,Array.Copy函数中也使用循环。 这就是所有的循环。 在某些情况下,更大的页面尺寸可能更有效率。

 public static string NormalizeNewLine(this string val) { if (string.IsNullOrWhiteSpace(val)) return val; const int page = 6; int a = page; int j = 0; int len = val.Length; char[] res = new char[len]; for (int i = 0; i < len; i++) { char ch = val[i]; if (ch == '\r') { int ni = i + 1; if (ni < len && val[ni] == '\n') { res[j++] = '\r'; res[j++] = '\n'; i++; } else { if (a == page) { //ensure capacity char[] nres = new char[res.Length + page]; Array.Copy(res, 0, nres, 0, res.Length); res = nres; a = 0; } res[j++] = '\r'; res[j++] = '\n'; a++; } } else if (ch == '\n') { int ni = i + 1; if (ni < len && val[ni] == '\r') { res[j++] = '\r'; res[j++] = '\n'; i++; } else { if (a == page) { //ensure capacity char[] nres = new char[res.Length + page]; Array.Copy(res, 0, nres, 0, res.Length); res = nres; a = 0; } res[j++] = '\r'; res[j++] = '\n'; a++; } } else { res[j++] = ch; } } return new string(res, 0, j); } 

我现在说'\ n \ r'实际上并没有在基础平台上使用。 但是:谁会连续使用两种types的换行符来表示2个换行符? 如果你想知道这一点,比你需要看看之前知道\ n和\ r两个在同一个文件中分开使用。