C#中的CompareTo方法如何比较字符串

3

我想知道C#的CompareTo方法如何比较两个字符串,所以我进行了如下测试:

string str1 = "0";
string str2 = "-";
Console.WriteLine(str1.CompareTo(str2)); // output : 1
string str3 = "01";
string str4 = "-1";
Console.WriteLine(str3.CompareTo(str4)); // output : -1

为什么结果会不同呢?

它使用 CultureInfo.CurrentCulture.CompareInfo.Compare,因此是文化设置决定排序顺序,但结果看起来非常奇怪。 - Dennis_E
1个回答

6
TLDR:默认的词典字符串排序对“-”字符有特殊处理。
答案是默认字符串比较使用词典排序规则。
这意味着一些符号 - 例如“-”将被特殊处理。 CompareOptions文档指出:
.NET Framework使用三种不同的排序方式:单词排序,字符串排序和序数排序。 单词排序对字符串进行区分文化的比较。某些非字母数字字符可能会被赋予特殊权重。例如,连字符(“-”)可能具有非常小的权重,使得“coop”和“co-op”在排序列表中相邻。 字符串排序与单词排序类似,但没有特殊情况。因此,所有非字母数字符号都排在所有字母数字字符之前。 序数排序根据字符串的每个元素的Unicode值进行比较。
在您的情况下,使用了默认排序:单词排序。

您可以通过在 string.Compare() 中指定所需的比较类型来查看不同的结果:

string str3 = "01";
string str4 = "-1";
Console.WriteLine(Math.Sign(string.Compare(str3, str4, StringComparison.InvariantCulture))); // output : -1
Console.WriteLine(Math.Sign(string.Compare(str3, str4, StringComparison.Ordinal)));          // output : 1

在这里,您可以看到它在不进行序数比较时特别处理-
实际上,是-被特别处理了 - 它并不假定它是一个减号。例如,如果您使用+而不是-,则会得到:
string str1 = "0";
string str2 = "+";
Console.WriteLine(Math.Sign(string.Compare(str1, str2, StringComparison.InvariantCulture))); // output : 1
Console.WriteLine(Math.Sign(string.Compare(str1, str2, StringComparison.Ordinal)));          // output : 1
string str3 = "01";
string str4 = "+1";
Console.WriteLine(Math.Sign(string.Compare(str3, str4, StringComparison.InvariantCulture))); // output : 1
Console.WriteLine(Math.Sign(string.Compare(str3, str4, StringComparison.Ordinal)));          // output : 1

旁注

不要将普通连字符与软连字符混淆!

  • 普通连字符的 Unicode 值为 \u002D
  • 软连字符的 Unicode 值为 \u00AD

请注意 具有示例代码的 string.Compare() 文档,其中显示了一个连字符被忽略的样例。文档指出:

字符集包括可忽略的字符。当使用基于区域性的比较时,Compare(String, String, Boolean) 方法不会考虑这些字符。

软连字符是一种可忽略的字符,但重要的是要注意软连字符与普通连字符不同。因此,本文档不适用于您的示例代码。

上述解释了普通连字符行为不同的实际原因。

如果你想获取Unicode中所有可忽略字符的完整列表,请访问http://www.unicode.org/Public/UNIDATA/DerivedCoreProperties.txt并搜索Default_Ignorable_Code_Point - 请注意,这个列表实际上不包括普通连字符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接