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

Tri*_*ong 7 c# string unicode substring indexof

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

简单代码(由 John 建议编辑):

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
Run Code Online (Sandbox Code Playgroud)

我测试的示例代码:

        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);
            }
        }
Run Code Online (Sandbox Code Playgroud)

Swe*_*per 7

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

...执行序数(不区分文化)搜索,其中一个字符仅在其 Unicode 标量值相同时才被视为等效于另一个字符。

IndexOf(string)...

使用当前区域性执行单词(区分大小写和区域性)搜索。

所以它比IndexOf(char)因为它考虑了当前文化的字符串比较规则要“聪明”得多。这就是它找不到空格字符的原因。

在其他语言和平台上进行了一些测试后,我怀疑这是 .NET Framework 的错误。因为在 .NET Core 3.1 中,b.IndexOf(" ")不返回 -1... b.IndexOf(' ', StringComparison.CurrentCulture). “ma? ?pr?znt”包含空间文化敏感的其他语言/平台包括:

  • 单声道 6
  • 斯威夫特 5

StringComparison.Ordinal作品传递:

b.IndexOf(" ", StringComparison.Ordinal)
Run Code Online (Sandbox Code Playgroud)

但请注意,您失去了对文化敏感的比较的智慧。