为什么string.Compare似乎不一致地处理重音字符?

Jon*_*han 15 c# sorting diacritics string-comparison

如果我执行以下语句:

string.Compare("mun", "mün", true, CultureInfo.InvariantCulture)
Run Code Online (Sandbox Code Playgroud)

结果为'-1',表示'mun'的数值低于'mün'.

但是,如果我执行此语句:

string.Compare("Muntelier, Schweiz", "München, Deutschland", true, CultureInfo.InvariantCulture)
Run Code Online (Sandbox Code Playgroud)

我得到'1',表明'Muntelier,Schewiz'应该排在最后.

这是比较中的错误吗?或者,更有可能的是,在排序包含重音的字符串时,我应该考虑一个规则


这是一个问题的原因是,我正在排序一个列表,然后做一个手动二进制过滤器,意味着让每个字符串以'xxx'开头.

以前我使用的是Linq'Fhere'方法,但现在我必须使用另一个人编写的这个自定义函数,因为他说它表现更好.

但是自定义函数似乎没有考虑.NET具有的"unicode"规则.因此,如果我告诉它过滤'mün',它就找不到任何项目,即使列表中的项目以'mun'开头.

这似乎是因为重音字符的顺序不一致,这取决于重音字符后面的字符.


好的,我想我已经解决了这个问题.

在过滤器之前,我根据每个字符串的前n个字母进行排序,其中n是搜索字符串的长度.

Adr*_*ian 23

工作中有一个打破平局的算法,请参阅http://unicode.org/reports/tr10/

为了解决语言敏感排序的复杂性,采用了多级比较算法.例如,在比较两个单词时,最重要的特征是基本字符:例如A和B之间的差异.如果基本字母有任何差异,则通常会忽略重音差异.如果基数或重音有任何差异,则通常会忽略大小写差异(大写与小写).标点符号是可变的.在某些情况下,标点符号被视为基本字符.在其他情况下,如果存在任何基础,重音或大小写差异,则应忽略它.也可能存在最终的打破平局级别,如果字符串中根本没有其他差异,则使用(标准化的)代码点顺序.

因此,"Munt ......"和"Münc..."按字母顺序不同,并根据"t"和"c"排序.

然而,"mun"和"mün"在字母上是相同的("u"等于"ü"在丢失的语言中)所以比较字符代码


Jon*_*eet 6

看起来重音字符只用于某种"打破平局"的情况 - 换句话说,如果字符串在其他方面是相同的.

以下是一些示例代码:

using System;
using System.Globalization;

class Test
{
    static void Main()
    {
        Compare("mun", "mün");
        Compare("muna", "münb");
        Compare("munb", "müna");
    }

    static void Compare(string x, string y)
    {
        int result = string.Compare(x, y, true, 
                                   CultureInfo.InvariantCulture));

        Console.WriteLine("{0}; {1}; {2}", x, y, result);
    }
}
Run Code Online (Sandbox Code Playgroud)

(我也尝试在"n"之后添加一个空格,看它是否在字边界上完成 - 它不是.)

结果:

mun; mün; -1
muna; münb; -1
munb; müna; 1
Run Code Online (Sandbox Code Playgroud)

我怀疑各种复杂的Unicode规则是正确的 - 但我对它们知之甚少.

至于你是否需要考虑到这一点......我不希望如此.这是怎么回事?