规范化 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
我相信这会满足您的需求:
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 是否在同一文档中单独使用。