规范化C#中的换行符

时间:2008-09-26 17:48:59

标签: c# .net

我有一个数据流可能包含\ 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

8 个答案:

答案 0 :(得分:35)

我相信这会做你需要的:

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 \ n转换为\ r \ n,但我不会调用该规范化。

答案 1 :(得分:6)

我和Regie Zawinski在RegEx:

“有些人在面对问题时会想”我知道,我会使用正则表达式。“现在他们有两个问题”

对于我们这些喜欢可读性的人:

  • 第1步

    用\ n

    替换\ r \ n

    用\ n替换\ n \ r \ n(如果你真的想要这个,有些海报似乎没有想到)

    用\ n

  • 替换\ r \ n
  • 第2步 用Environment.NewLine或\ r \ n或其他替换\ n。

答案 2 :(得分:3)

正则表达式会帮助..可以做一些像这样的事情......

(\ 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 

答案 3 :(得分:2)

这是一个两步过程。
首先,将\r\n的所有组合转换为单个组合,例如\r
然后,您将所有\r转换为目标\r\n

normalized = 
    original.Replace("\r\n", "\r").
             Replace("\n\r", "\r").
             Replace("\n", "\r").
             Replace("\r", "\r\n"); // last step

答案 4 :(得分:1)

你觉得太复杂了。 忽略每个\ r并将每个\ n转换为\ r \ n。

在Pseudo-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 \ n单独没有行终结符,所以我怀疑你真的想将\ r \ n扩展到\ r \ n。

答案 5 :(得分:1)

我同意正则表达式是答案,但是,其他人都没有提到Unicode行分隔符。应包括那些(及其与\ n的变体)。

答案 6 :(得分:1)

规范化休息时间,使它们全部为{ "a": {"language": "python"}, " }

\r\n

答案 7 :(得分:1)

这是问题的答案。给定的解决方案用给定的转换表替换字符串。 它不使用昂贵的正则表达式函数。 它也不使用多个替换函数,每个函数都通过多次检查等单独循环数据。

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

public static string NormalizeNewLine(this string val)
{
    if (string.IsNullOrEmpty(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'实际上没有在基本平台上使用,翻译表也真的很吸引我。谁会使用两种类型的换行符来表示2个换行符? 如果您想知道这一点,那么您需要先了解一下\ n和\ r \ n是否在同一文档中单独使用。