c# - 无法在字符串中搜索换行符

标签 c# string newline indexof

在 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/

相关文章:

shell - 如何用每个只有 1 个空行替换许多中间空行

c# - 将 XMLDocument 写入具有特定换行符的文件 (c#)

c# - WebJob 使用多种方法抛出 FunctionIndexingException

c# - 我可以强制对 IDisposable 类的实例使用 'using' 语句吗?

c# - 有没有办法通过委托(delegate)直接调用属性 setter ?

c# - 有没有办法判断一个对象是否在 C# 中显式实现了 ToString

python - 如何将文件中的字符串更改为列表中的字符串

c - 在 C 程序中将文件中的换行符读取为 char

java - 如何从多种可能性中找到负责输出字符串的特定java源文件

java - 我们什么时候应该将 String 更改为 Stringbuilder?