规范化 C# 中的换行符

本文关键字:换行符 规范化 | 更新日期: 2023-09-27 17:47:21

我有一个数据流,可能包含''r,',''r','''r或它们的任意组合。 有没有一种简单的方法来规范化数据,使它们全部简单地变成''r'对,以使显示更加一致?

所以会产生这种转换表:

'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

规范化 C# 中的换行符

我相信这会满足您的需求:

using System.Text.RegularExpressions;
// ...
string normalized = Regex.Replace(originalString, @"'r'n|'n'r|'n|'r", "'r'n");

我不能 100% 确定确切的语法,而且我没有方便检查的 .Net 编译器。 我用perl编写了它,并将其转换为(希望是正确的)C#。 唯一真正的技巧是先匹配"''r'"和"'''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
<小时 />

更新:现在将 '''r 转换为 ''r',尽管我不会称之为规范化。

我和Jamie Zawinski一起在RegEx上:

"有些人在遇到问题时会想'我知道,我会使用正则表达式'。现在他们有两个问题"

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

  • 步骤 1

    将 ''r' 替换为 '

    将 '''r 替换为 '(如果你真的想要这个,有些海报似乎不认为)

    将 ''r 替换为 '

  • 步骤 2将 ' 替换为 Environment.NewLine 或 ''r' 或其他任何内容。

自.

NET 6以来,它开箱即用地受支持:

string normalized = originalString.ReplaceLineEndings(); //uses Environment.NewLine
string normalized = originalString.ReplaceLineEndings("'r'n");

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

正则表达式会有所帮助......可以大致做这样的事情。

(''r'|''|'''r|''

r|') 替换为 ''r'

这个正则表达式从发布的表格中产生了这些结果(只是测试左侧),因此替换应该规范化。

'r   => 'r 
'n   => 'n 
'n'n => 'n'n 
'n'r => 'n'r 
'r'n => 'r'n 
'r'n => 'r'n 
'n   => 'n 

规范化中断,以便它们都'r'n

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

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

你想得太复杂了。忽略每个 ''r,并将每个 ' 转换为 ''r'。

在伪 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'。

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

因此,搜索直接在 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);
}

即使"'''r"实际上并未在基本平台上使用,转换表也确实吸引了我。谁会使用两种类型的换行符来表示 2 个换行符?如果您想知道这一点,那么您需要先看看 ' 和 ''r 是否在同一文档中单独使用。