Joe*_*nos 3 c# string newline indexof
在 C# 中,我正在查找字符串内字符串的索引 - 特别是换行符 ( \n) 字符所在的索引。
给定一个带有 Windows 换行符 ( \r\n) 的字符串:
如果我寻找"\n",它会给我-1。如果我寻找"\r\n",我就会得到结果。如果我寻找'\n'一个角色,我就会得到结果。
Given a string with Unix line breaks (\n), I get a result.
string s = "hello\r\nworld";
Console.WriteLine(@"\r\n index: " + s.IndexOf("\r\n")); // 5
Console.WriteLine(@"\n index as string: " + s.IndexOf("\n")); // -1
Console.WriteLine(@"\n index as char: " + s.IndexOf('\n')); // 6
s = "hello\nworld";
Console.WriteLine(@"\n index as string: " + s.IndexOf("\n")); // 5
Console.WriteLine(@"\n index as char: " + s.IndexOf('\n')); // 5
Run Code Online (Sandbox Code Playgroud)
I understand that line breaks are two characters, and if I was using StreamReader or File.ReadAllLines or something like that, then it would be handled automatically and I'd lose them.
I thought \n was a valid string by itself, and that \r\n, while special, still represented two separate and distinct characters in a string. But this is telling me otherwise.
I can do IndexOf on the character instead of the string ('\n' instead of "\n"), but I'd really like to know why this is happening so I can plan for it.
EDIT
仅供参考:刚刚发现将字符串转换为 aSpan给出了正确的结果。不确定其中涉及的开销,所以我不知道这与序数解决方案相比如何 - 我猜序数是更好的解决方案:
Console.WriteLine(@"\n index as string Ordinal: "
+ s.IndexOf("\n", StringComparison.Ordinal)); // 6
Console.WriteLine(@"\n index as Span: "
+ s.AsSpan().IndexOf("\n".AsSpan())); // 6
Console.WriteLine(@"\n index as string with s.AsSpan(): "
+ s.AsSpan().IndexOf("\n")); // 6
Run Code Online (Sandbox Code Playgroud)
.Net 5.0 中的 Windows 全球化库发生了变化。在以前的版本中,NLS 用于 Windows 上,ICU 用于 Unix 上。.Net 5 在两者上都使用 ICU 来使跨平台开发保持一致,但代价是让 Windows 开发人员感到惊讶(叹息)。由于此更改,您必须通过StringComparison.Ordinal在字符串中查找换行符。
请注意,这也可能取决于 Windows 的版本(双重叹息),因为 Windows 10 May 2019 包含 ICU 库,而早期版本不包含 ICU,这将导致 .Net 5 回退到 NLS。
请参阅Microsoft 的 这篇文章。本文提供了有关受影响的 API 的更多详细信息。