c# - 为什么在使用 IndexOf(string) 和 IndexOf(char) 时,非组合变音符号前面的空格会产生不同的作用?

标签 c# string unicode substring indexof

我正在从一个带有空格后的非组合变音符号的字符串中创建一个子字符串。这样做时,我使用 .Contains() 检查字符串。然后执行子串。当我使用空格时 char内部 .IndexOf() ,程序按预期执行,但在 .IndexOf() 内使用字符串“”时程序抛出异常。如下面的示例所示,只有一个 string在主要重音变音符号 (U+02C8) 之前抛出 ArgumentOutOfRangeException .
简单代码(约翰建议的编辑):

string a = "aɪ prɪˈzɛnt";
string b = "maɪ ˈprɛznt";

// A            
Console.WriteLine(a.IndexOf(" ")); // string index:  2
Console.WriteLine(a.IndexOf(' ')); // char index:    2

// B    
Console.WriteLine(b.IndexOf(" ")); // string index: -1
Console.WriteLine(b.IndexOf(' ')); // char index:    3
我测试的示例代码:
        const string iPresent = "aɪ prɪˈzɛnt",
                     myPresent = "maɪ ˈprɛznt";

        if(iPresent.Contains(' '))
        {
            Console.WriteLine(iPresent.Substring(0, iPresent.IndexOf(' ')));
        }

        if(iPresent.Contains(" "[0]))
        {
            Console.WriteLine(iPresent.Substring(0, iPresent.IndexOf(" "[0])));
        }

        if(iPresent.Contains(" "))
        {
            Console.WriteLine(iPresent.Substring(0, iPresent.IndexOf(" ")));
        }

        if(iPresent.Contains(string.Empty + ' '))
        {
            Console.WriteLine(iPresent.Substring(0, iPresent.IndexOf(string.Empty + ' ')));
        }

        if (myPresent.Contains(' '))
        {
            Console.WriteLine(myPresent.Substring(0, myPresent.IndexOf(' ')));
        }

        if (myPresent.Contains(" "[0]))
        {
            Console.WriteLine(myPresent.Substring(0, myPresent.IndexOf(" "[0])));
        }

        if (myPresent.Contains(string.Empty + ' '))
        {
            try
            {
                Console.WriteLine(myPresent.Substring(0, myPresent.IndexOf(string.Empty + ' ')));
            }
            catch (Exception ex)
            {
                Console.WriteLine("***" + ex.Message);
            }
        }

        if (myPresent.Contains(" "))
        {
            try
            {
                Console.WriteLine(myPresent.Substring(0, myPresent.IndexOf(" ")));
            }
            catch (Exception ex)
            {
                Console.WriteLine("***" + ex.Message);
            }
        }

最佳答案

IndexOf(string) 做一些与 IndexOf(char) 不同的事情, 因为 IndexOf(char) ...

...performs an ordinal (culture-insensitive) search, where a character is considered equivalent to another character only if their Unicode scalar values are the same.


IndexOf(string) ...

performs a word (case-sensitive and culture-sensitive) search using the current culture.


所以它比 IndexOf(char) 更“聪明”因为它考虑了当前文化的字符串比较规则。这就是它找不到空格字符的原因。
在其他语言和平台上进行了一些测试后,我怀疑这是 .NET Framework 的错误。因为在 .NET Core 3.1 中,b.IndexOf(" ")不返回 -1 ... b.IndexOf(' ', StringComparison.CurrentCulture) 也不返回. “maɪ ˈprɛznt”包含空间文化敏感的其他语言/平台包括:
  • 单声道 6
  • swift 5

  • 路过 StringComparison.Ordinal作品:
    b.IndexOf(" ", StringComparison.Ordinal)
    
    但请注意,您失去了对文化敏感的比较的智慧。

    关于c# - 为什么在使用 IndexOf(string) 和 IndexOf(char) 时,非组合变音符号前面的空格会产生不同的作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62667650/

    相关文章:

    c# - 选择具有不同别名和不同条件的同一列

    c# - 插入数据并用新数据刷新数据网格后关闭弹出窗口

    python - 每两个逗号切割字符串

    python - 带有 unicode 的简单 json 转储功能

    javascript - Node.JS 大端 UCS-2

    c# - 从以 int[] 数组作为值的字典中获取

    c# - 复合字符串格式的 String.Format 变量

    ios - 如何在 Swift 3 中将 CoreData 日期转换为日期时间

    ASP.NET 将字符编码更改为 windows-1252

    c# - 线程 :Lock on generic dictionary