为什么 "\u1FFF:foo".StartsWith(":") return 为真?
Why does "\u1FFF:foo".StartsWith(":") return true?
字符串 "\u1FFF:foo"
以 \u1FFF
(或“”)开头,对吧?
那么这两个怎么可能是真的呢?
"\u1FFF:foo".StartsWith(":") // equals true
"\u1FFF:foo".StartsWith("\u1FFF") // equals true
// alternatively, the same:
":foo".StartsWith(":") // equals true
":foo".StartsWith("") // equals true
.NET 是否声称此字符串以两个不同的字符开头?
虽然我发现这 非常 令人惊讶并且想了解 "why",但我同样对如何强制 .NET 仅通过以下方式进行搜索感兴趣codepoints 而不是(使用 InvariantCulture
似乎没有做任何事情)?
为了比较,再往下一个字符,"\u1FFE:foo".StartsWith(":")
returns false.
一个字符串通常可以被认为以两个不同的字符串开头,这两个字符串不是逐字节相同的,这并不奇怪(因为 Unicode 很复杂)。例如,这些结果几乎总是会反映用户的需求:
"n\u0303".StartsWith("\u00f1") // true
"n\u0303".StartsWith("n") // false
使用System.Globalization.CharUnicodeInfo.GetUnicodeCategory
,可以看到'\u1fff'
属于"OtherNotAssigned"类;我不清楚这是否会影响字符串 search/sort/comparison 操作(它似乎不影响规范化,也就是说,字符在规范化后仍然存在)。
如果要逐字节比较,请使用 StringComparison.Ordinal
。
因为您使用的 String.StartsWith()
不正确。您应该使用 String.StartsWith (String, StringComparison)
重载和 StringComparison.Ordinal
.
没有分配给 \u1FFF
的字符。 IE。该代码没有任何语言含义。请参阅来自 MSDN 的 Greek Extended, Range: 1F00–1FFF excerpt from character code tables for Unicode Standard. Best Practices for Using Strings in .NET 文档明确指出,如果您需要以忽略自然语言特征的方式比较字符串,那么您应该使用 StringComparison.Ordinal
:
Specifying the StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase value in a method call signifies a non-linguistic comparison in which the features of natural languages are ignored. Methods that are invoked with these StringComparison values base string operation decisions on simple byte comparisons instead of casing or equivalence tables that are parameterized by culture. In most cases, this approach best fits the intended interpretation of strings while making code faster and more reliable.
此外,它建议在此类方法调用中始终明确指定 StringComparison
:
When you develop with .NET, follow these simple recommendations when you use strings:
- Use overloads that explicitly specify the string comparison rules for string operations. Typically, this involves calling a method overload that has a parameter of type StringComparison.
字符串 "\u1FFF:foo"
以 \u1FFF
(或“”)开头,对吧?
那么这两个怎么可能是真的呢?
"\u1FFF:foo".StartsWith(":") // equals true
"\u1FFF:foo".StartsWith("\u1FFF") // equals true
// alternatively, the same:
":foo".StartsWith(":") // equals true
":foo".StartsWith("") // equals true
.NET 是否声称此字符串以两个不同的字符开头?
虽然我发现这 非常 令人惊讶并且想了解 "why",但我同样对如何强制 .NET 仅通过以下方式进行搜索感兴趣codepoints 而不是(使用 InvariantCulture
似乎没有做任何事情)?
为了比较,再往下一个字符,"\u1FFE:foo".StartsWith(":")
returns false.
一个字符串通常可以被认为以两个不同的字符串开头,这两个字符串不是逐字节相同的,这并不奇怪(因为 Unicode 很复杂)。例如,这些结果几乎总是会反映用户的需求:
"n\u0303".StartsWith("\u00f1") // true
"n\u0303".StartsWith("n") // false
使用System.Globalization.CharUnicodeInfo.GetUnicodeCategory
,可以看到'\u1fff'
属于"OtherNotAssigned"类;我不清楚这是否会影响字符串 search/sort/comparison 操作(它似乎不影响规范化,也就是说,字符在规范化后仍然存在)。
如果要逐字节比较,请使用 StringComparison.Ordinal
。
因为您使用的 String.StartsWith()
不正确。您应该使用 String.StartsWith (String, StringComparison)
重载和 StringComparison.Ordinal
.
没有分配给 \u1FFF
的字符。 IE。该代码没有任何语言含义。请参阅来自 MSDN 的 Greek Extended, Range: 1F00–1FFF excerpt from character code tables for Unicode Standard. Best Practices for Using Strings in .NET 文档明确指出,如果您需要以忽略自然语言特征的方式比较字符串,那么您应该使用 StringComparison.Ordinal
:
Specifying the StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase value in a method call signifies a non-linguistic comparison in which the features of natural languages are ignored. Methods that are invoked with these StringComparison values base string operation decisions on simple byte comparisons instead of casing or equivalence tables that are parameterized by culture. In most cases, this approach best fits the intended interpretation of strings while making code faster and more reliable.
此外,它建议在此类方法调用中始终明确指定 StringComparison
:
When you develop with .NET, follow these simple recommendations when you use strings:
- Use overloads that explicitly specify the string comparison rules for string operations. Typically, this involves calling a method overload that has a parameter of type StringComparison.