为什么在使用 IndexOf(string) 和 IndexOf(char) 时,space 前面的非组合变音符号的功能不同?
Why does a space preceding a non-combining diacritic function differently when using IndexOf(string) and IndexOf(char)?
我正在从 space 后带有非组合变音符号的字符串创建子字符串。这样做时,我用 .Contains()
检查字符串,然后执行子字符串。当我在 .IndexOf()
内使用 space char
时,程序按预期执行,但在 .IndexOf()
内使用字符串“”时,程序会抛出异常。如下面的示例所示,只有 主重音 变音符号 (U+02C8) 之前的 string
会引发 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
我测试的示例代码:
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)
does something different from 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)
“聪明”很多,因为它考虑了当前文化的字符串比较规则。 这就是它找不到 space 字符的原因。
经过其他语言和平台的一些测试,我怀疑这是.NET Framework 的一个错误。因为在 .NET Core 3.1 中,b.IndexOf(" ")
不会 return -1... b.IndexOf(' ', StringComparison.CurrentCulture)
. 也不会 languages/platforms 其中“maɪ ˈprɛznt”包含space 文化敏感包括:
- 单声道 6
- Swift 5
传入 StringComparison.Ordinal
有效:
b.IndexOf(" ", StringComparison.Ordinal)
但请注意,您失去了文化敏感比较的智慧。
我正在从 space 后带有非组合变音符号的字符串创建子字符串。这样做时,我用 .Contains()
检查字符串,然后执行子字符串。当我在 .IndexOf()
内使用 space char
时,程序按预期执行,但在 .IndexOf()
内使用字符串“”时,程序会抛出异常。如下面的示例所示,只有 主重音 变音符号 (U+02C8) 之前的 string
会引发 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
我测试的示例代码:
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)
does something different from 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)
“聪明”很多,因为它考虑了当前文化的字符串比较规则。 这就是它找不到 space 字符的原因。
经过其他语言和平台的一些测试,我怀疑这是.NET Framework 的一个错误。因为在 .NET Core 3.1 中,b.IndexOf(" ")
不会 return -1... b.IndexOf(' ', StringComparison.CurrentCulture)
. 也不会 languages/platforms 其中“maɪ ˈprɛznt”包含space 文化敏感包括:
- 单声道 6
- Swift 5
传入 StringComparison.Ordinal
有效:
b.IndexOf(" ", StringComparison.Ordinal)
但请注意,您失去了文化敏感比较的智慧。