我试图处理以下角色:⨝(http://www.fileformat.info/info/unicode/char/2a1d/index.htm)
如果你检查一个以这个字符开头的空字符串,它总是返回true,这没有任何意义!那是为什么?
// visual studio 2008 hides lines that have this char literally (bug in visual studio?!?) so i wrote it's unicode instead.
char specialChar = (char)10781;
string specialString = specialChar.ToString();
// prints 1
Console.WriteLine(specialString.Length);
// prints 10781
Console.WriteLine((int)specialChar);
// prints false
Console.WriteLine(string.Empty.StartsWith("A"));
// both prints true WTF?!?
Console.WriteLine(string.Empty.StartsWith(specialString));
Console.WriteLine(string.Empty.StartsWith(((char)10781).ToString()));
答案 0 :(得分:11)
您可以使用ordinal StringComparison修复此错误:
来自MSDN文档:
指定时 StringComparison.Ordinal或 StringComparison.OrdinalIgnoreCase, 字符串比较将是 非语言。也就是说,功能 这是特定于自然的 制作时会忽略语言 比较决定。这意味着 决策基于简单的字节 比较并忽略套管或 等价表 由文化参数化。结果是, 通过显式设置参数 StringComparison.Ordinal或者 StringComparison.OrdinalIgnoreCase, 你的代码经常获得速度,增加 正确性,变得更多 可靠。
char specialChar = (char)10781;
string specialString = Convert.ToString(specialChar);
// prints 1
Console.WriteLine(specialString.Length);
// prints 10781
Console.WriteLine((int)specialChar);
// prints false
Console.WriteLine(string.Empty.StartsWith("A"));
// prints false
Console.WriteLine(string.Empty.StartsWith(specialString, StringComparison.Ordinal));
答案 1 :(得分:4)
好的unicode故障;-p
我不确定为什么会这样做,但有趣的是:
Console.WriteLine(string.Empty.StartsWith(specialString)); // true
Console.WriteLine(string.Empty.Contains(specialString)); // false
Console.WriteLine("abc".StartsWith(specialString)); // true
Console.WriteLine("abc".Contains(specialString)); // false
我猜这有点像Jon mentioned at devdays的非加入角色;一些字符串函数看到它,有些则不看。如果它没有看到它,那就变成“do(某些字符串)以空字符串开头”,总是为真。
答案 2 :(得分:4)
这个的根本原因是默认的字符串比较是语言环境感知。这意味着使用区域设置数据表进行比较(包括相等)。
许多(如果不是大多数)Unicode字符对于许多语言环境没有任何价值,因此不存在(或者做,但匹配任何东西,或者什么都没有)。
在Michael Kaplan的博客“Sorting It All Out”上查看关于角色权重的条目。 This series博客包含大量背景信息(API是原生的,但据我所知 - .NET中的机制是相同的。)
快速版:这是一个复杂的领域(正常语言)比较权利很难,这往往会导致语言之外的字形代码点奇怪。