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

C# 为什么string.Compare似乎处理重音字符不一致?,c#,sorting,diacritics,string-comparison,C#,Sorting,Diacritics,String Comparison,如果我执行以下语句: string.Compare("mun", "mün", true, CultureInfo.InvariantCulture) string.Compare("Muntelier, Schweiz", "München, Deutschland", true, CultureInfo.InvariantCulture) 结果是“-1”,表示“mun”的数值低于“mün” 但是,如果我执行此语句: string.Compare("mun", "mün", true, C

如果我执行以下语句:

string.Compare("mun", "mün", true, CultureInfo.InvariantCulture)
string.Compare("Muntelier, Schweiz", "München, Deutschland", true, CultureInfo.InvariantCulture)
结果是“-1”,表示“mun”的数值低于“mün”

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

string.Compare("mun", "mün", true, CultureInfo.InvariantCulture)
string.Compare("Muntelier, Schweiz", "München, Deutschland", true, CultureInfo.InvariantCulture)
我得到“1”,表示“Muntelier,Schewiz”应该排在最后

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


这是一个问题的原因是,我正在对一个列表进行排序,然后进行手动二进制筛选,以获取以“xxx”开头的每个字符串

以前我使用Linq'Where'方法,但现在我不得不使用另一个人编写的自定义函数,因为他说它性能更好

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

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


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


在筛选之前,我根据每个字符串的前n个字母进行排序,其中n是搜索字符串的长度。

看起来重音字符仅在某种“平局中断”情况下使用,换句话说,如果字符串在其他方面相等

下面是一些要演示的示例代码:

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);
    }
}
(我也试过在“n”后面加一个空格,看看是否在单词边界上加了空格——事实并非如此。)

结果:

mun; mün; -1
muna; münb; -1
munb; müna; 1
我怀疑各种复杂的Unicode规则都是正确的,但我对它们了解得不够


至于你是否需要考虑到这一点。。。我没料到会这样。你在做什么?据我所知,这还是有点一致的。使用
CultureInfo.InvariantCulture
进行比较时,umlaut字符
u
被视为非重音字符
u

由于第一个示例中的字符串显然不相等,因此结果将不是0而是-1(这似乎是默认值)。在第二个例子中,蒙特勒排在最后,因为字母表中t跟在c后面

我在MSDN中找不到任何解释这些规则的清晰文档,但我发现

string.Compare("mun", "mün", CultureInfo.InvariantCulture,  
    CompareOptions.StringSort);

给出了期望的结果


无论如何,我认为您最好基于特定的区域性进行排序,例如当前用户的区域性(如果可能)。

有一种打破平局的算法,请参阅

解决问题的复杂性 语言敏感排序 提出了多级比较算法 雇佣。在比较两个词时 例如,最重要的特性是 基本字符:例如 A和B之间的区别。 口音差异通常是 忽略,如果存在任何差异 用大写字母写。案例差异 (大写与小写),是 通常被忽略(如果有) 基调或口音上的差异。 标点符号是可变的。在某些方面 使用标点符号的情况 被当作基本角色对待。在里面 在其他情况下,应该忽略它 如果有基音、重音或大小写 差异。也可能有一个 最终,打破平局水平,如果 没有任何其他区别 在字符串中,是(规范化的)代码 使用点顺序

所以,“Munt…”和“Münc…”在字母顺序上是不同的,并根据“t”和“c”排序


然而,“mun”和“mün”在字母顺序上是相同的(“u”在失落的语言中相当于“ü”),所以字符代码是比较的

就是这样的时刻,我希望.NET Framework是开源的,因此,我可以在调试模式下单步执行,并准确地了解它在做什么。@jonathanconway:单步执行基类库的源代码是可能的,请参阅@divo谢谢您的参考。从未意识到这是可能的<代码>比较选项。序号也可以是一个选项。使用此选项,将根据Unicode值比较字符串。看见