.net 在C#中规范化换行符

kzmpq1sx  于 2023-01-18  发布在  .NET
关注(0)|答案(8)|浏览(117)

我的数据流可能包含\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
x7rlezfr

x7rlezfr1#

我相信这会满足你的需要:

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”。
要将它应用于整个流,只需在输入块上运行它(如果需要,可以使用流 Package 器来完成此操作)。
原始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,尽管我不会称之为规范化。

lsmepo6l

lsmepo6l2#

我和杰米·扎文斯基一起在RegEx上:
有些人在遇到问题时会想:"我知道了,我会用正则表达式。"现在他们有两个问题了
对于我们这些喜欢可读性的人来说:

  • 第一步

替换\r\n为\n
将\n\r替换为\n(如果您真的想要这样做,有些发帖者似乎不这么认为)
替换\r为\n

  • 步骤2将\n替换为Environment. NewLine或\r\n或其他内容。
hec6srdp

hec6srdp3#

一个正则表达式会有帮助..可以做大致这样的事情..
(\r\n|\n\n|\n|\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
disho6za

disho6za4#

规范化中断,使其全部为\r\n

var normalisedString =
            sourceString
            .Replace("\r\n", "\n")
            .Replace("\n\r", "\n")
            .Replace("\r", "\n")
            .Replace("\n", "\r\n");
e37o9pze

e37o9pze5#

这是一个两步的过程。
首先,将\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
yrwegjxp

yrwegjxp6#

你想得太复杂了。忽略每一个\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);
   }
 }

EDIT:\r单独没有行终止符,因此我怀疑您是否真的要将\r扩展为\r\n。

vohkndzv

vohkndzv7#

自. NET 6以来,它即受支持:

string normalized = originalString.ReplaceLineEndings(); //uses Environment.NewLine

string normalized = originalString.ReplaceLineEndings('\r\n');

参见www.example.comhttps://github.com/dotnet/runtime/blob/a879885975b5498db559729811304888463c15ed/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs#L1183

xe55xuns

xe55xuns8#

这就是问题的答案。给定的解决方案用给定的转换表替换字符串。它不使用昂贵的regex函数。它也不使用多个替换函数,每个函数都要对数据进行循环检查等。
因此,搜索直接在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两者是否在同一个文档中单独使用。

相关问题