字符串"\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是否声称此字符串以两个不同的字符开头?
虽然我发现这个非常令人惊讶,并且想要了解“为什么”,但我同样对如何强制.NET仅通过代码点进行搜索感兴趣(使用{{1好像什么都没做?)
为了进行比较,下面有一个字符,InvariantCulture
返回false。
答案 0 :(得分:9)
一般来说,一个字符串可能被认为是以两个不同字节相同的字符串开头,这并不奇怪(因为Unicode很复杂)。例如,这些结果几乎总是反映用户的需求:
"n\u0303".StartsWith("\u00f1") // true
"n\u0303".StartsWith("n") // false
使用System.Globalization.CharUnicodeInfo.GetUnicodeCategory
,您可以看到'\u1fff'
位于“OtherNotAssigned”类别中;我不清楚这是否应该影响字符串搜索/排序/比较操作(它似乎不会影响规范化,也就是说,正常化后字符仍然存在)。
如果要进行逐字节比较,请使用StringComparison.Ordinal
。
答案 1 :(得分:1)
因为您错误地使用了String.StartsWith()
。您应该使用String.StartsWith (String, StringComparison)
重载和StringComparison.Ordinal
。
没有为\u1FFF
分配字符。即此代码没有附加语言含义。有关Unicode标准的字符代码表,请参阅Greek Extended, Range: 1F00–1FFF摘录。来自MSDN的Best Practices for Using Strings in .NET文档明确指出,如果您需要以忽略自然语言功能的方式比较字符串,那么您应该使用StringComparison.Ordinal
:
在方法调用中指定StringComparison.Ordinal或StringComparison.OrdinalIgnoreCase值表示忽略自然语言功能的非语言比较。使用这些StringComparison值调用的方法基于简单字节比较的字符串操作决策,而不是由culture进行参数化的大小写或等价表。在大多数情况下,这种方法最适合字符串的预期解释,同时使代码更快,更可靠。
此外,它建议始终在此类方法调用中明确指定StringComparison
:
使用.NET进行开发时,请在使用字符串时遵循以下简单建议:
- 使用显式指定字符串操作的字符串比较规则的重载。通常,这涉及调用具有StringComparison类型参数的方法重载。