在 C# 中,我在字符串中查找字符串的索引 - 特别是换行符 (\n
) 所在的索引。
给定一个带有 Windows 换行符的字符串 (\r\n
):
如果我查找 "\n"
,它会给我 -1。如果我查找 "\r\n"
,我会得到一个结果。如果我寻找 '\n'
作为一个字符,我会得到一个结果。
给定一个带有 Unix 换行符 (\n
) 的字符串,我得到一个结果。
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
我知道换行符是两个字符,如果我使用 StreamReader 或 File.ReadAllLines 或类似的东西,那么它会自动处理,我会丢失它们。
我认为 \n
本身就是一个有效的字符串,而 \r\n
虽然很特殊,但仍然表示字符串中的两个独立且不同的字符。但这告诉我不是这样。
我可以对字符而不是字符串执行 IndexOf('\n'
而不是 "\n"
),但我真的很想知道为什么这正在发生,所以我可以计划一下。
编辑
仅供引用:刚刚发现将字符串转换为 Span
可以得到正确的结果。不确定其中涉及的开销,所以我不知道这与 Ordinal 解决方案相比如何 - 我猜 Ordinal 是更好的解决方案:
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
最佳答案
.Net 5.0 中针对 Windows 的全局化库发生了变化。在以前的版本中,NLS 在 Windows 上使用,在 Unix 上使用 ICU。 .Net 5 在两者上都使用 ICU 以使跨平台开发保持一致,但代价是让 Windows 开发人员感到惊讶(sigh)。由于此更改,您必须通过 StringComparison.Ordinal
才能在字符串中查找换行符。
请注意,这也可能取决于 Windows 的版本(双 sigh),因为 2019 年 5 月 10 日的 Windows 包括 ICU 库和不会导致 .Net 5 回退到的早期版本NLS。
见 this article来自微软。 This article有关受影响的 API 的更多详细信息。
关于c# - 无法在字符串中搜索换行符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69473410/