【问题标题】:C# Compare strings with umlaut strange resultsC#比较字符串与变音符号奇怪的结果
【发布时间】:2021-03-14 09:43:07
【问题描述】:

我使用string.Compare(strA, strB, true, CultureInfo.CurrentCulture); 并且不理解结果。 CurrentCulture 是“de-DE”。

string.Compare( "o", "ö", true, CultureInfo.CurrentCulture) // result: -1 
string.Compare( "d", "f", true, CultureInfo.CurrentCulture) // result: -1 
string.Compare( "dx", "fa", true, CultureInfo.CurrentCulture) // result: -1 
string.Compare( "ox", "öa", true, CultureInfo.CurrentCulture) // result: 1 
string.Compare( "oa", "öx", true, CultureInfo.CurrentCulture) // result: -1

为什么结果取决于第二个字母在最后两行得到不同的结果? 如果 o 是第一个,ö 是下一个,第 4 行不应该也返回 -1 吗? 有人可以解释一下吗?

解释为什么我有这个问题比较一些代码:

class Program
    {
        public class ComparerB : IComparer<string>
        {
            public int Compare(string x, string y)
            {
                return string.CompareOrdinal(x, y);
            }
        }

        public class ComparerA : IComparer<string>
        {
            public int Compare(string x, string y)
            {
                return string.Compare(x, y, true, CultureInfo.CurrentCulture);
            }
        }

        static void Main(string[] args)
        {
            List<string> list = new List<string>();
            list.Add("Update");
            list.Add("Ö3 Greatest Hits");
            list.Add("Dont sleep");
            list.Add("Friends");
            list.Add("Dart vadder");
            list.Add("Family");
            list.Add("Oxfort");
            list.Add("Ödipus");
            list.Add("Oasis");
            list.Add("Österreich");
            list.Add("Panda");

            list.Sort(new ComparerA());
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine();
            list.Sort(new ComparerB());
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

            Console.ReadLine();
        }
    }

使用 ComparerA 的结果是(混合 Ö 和 O):

飞镖飞镖
不要睡觉
家庭
朋友
Ö3 精选
绿洲
奥狄普斯
奥地利
牛津大学
熊猫
更新

使用 ComparerB 的结果是(Ö 在列表末尾):

飞镖飞镖
不要睡觉
家庭
朋友
绿洲
牛津大学
熊猫
更新
Ö3 精选
奥狄普斯
奥斯特雷赫

但我需要的是这个(O 之后的Ö):

飞镖飞镖
不要睡觉
家庭
朋友
绿洲
牛津大学
Ö3 精选
奥狄普斯
奥地利
熊猫
更新

【问题讨论】:

  • 你期望得到什么?因为我们大多数人不懂德语
  • 这是预期的结果:"大于零:strA 在排序顺序中跟随 strB。"。请参阅 [String.Compare(String, String, Boolean, CultureInfo) ](docs.microsoft.com/en-us/dotnet/api/…)。您希望比较平等吗?
  • 如果我使用它对列表进行排序,我会得到 O 和 Ö 的混合。如果我使用 CompareOrdianl,我得到的结果不会混合,但特殊字符位于列表末尾。我想得到一个排序如下的列表:首先是 O,然后是 Ö。
  • 如果您愿意,您可以定义您自己的 CultureInfo,其中Ö 排在O 之前。但是在德语中,显然是由微软和大概其他人实施的,它们的排序方式不同。您可以进行反向排序,但显然这也会对其他字符进行不同的排序。
  • 德语字母表在 Z 之后排序了 ÄÖÜ。因此,ComparerB 示例似乎“正确”工作。见:en.wikipedia.org/wiki/German_orthography “[元音变音] 被官方认为是字母表中不同的字母。”所以它们不仅仅是AOU的“特殊种类”。 - 不过,对你没有帮助。也许有一种方法可以创建你自己的IComparer&lt;string&gt;,但这可能很快就会变成你不想把手伸进去的蜂巢。

标签: c# string compare


【解决方案1】:

在您的比较器 A 中,您有代码

return string.Compare(x, y, true, CultureInfo.CurrentCulture);

这意味着您使用的是CurrentCulture,我相信这是德语,所以我在互联网上注意到的德语字母顺序如下

A、B、C、D、E、F、G、H、I、J、K、L、M、N、O、P、Q、R、S、T、 U、V、W、X、Y、Z、Ä、Ö、Ü、ß

所以,排序会相应地进行,所以你现在得到的是正确的我相信,但如果你仍然需要按照你的意愿去做并且你愿意使用另一个 strong> CultureInfo 其中O, Ö 的序列就跟土耳其语"tr-TR" 一样,那么代码应该是这样的:

return string.Compare(x, y, true, new CultureInfo("tr-TR"));

这会给你以下结果:

Dart vadder
Dont sleep
Family
Friends
Oasis
Oxfort
Ö3 Greatest Hits
Ödipus
Österreich
Panda
Update

另一种选择是开发您的自定义排序算法和函数,以考虑您喜欢的任何字符序列。

【讨论】:

  • 谢谢。有了“tr-TR”,我得到了我想要的。我已经尝试过“de-DE_phoneb”,但没有任何改变。
  • 为此感到高兴:)
【解决方案2】:

我认为在德语字母表中,特殊字符 ö 在内部由 oe 表示。

所以string.Compare( "o", "ö", true, System.Globalization.CultureInfo.CurrentCulture); 相当于string.Compare( "o", "oe", true, System.Globalization.CultureInfo.CurrentCulture);

string.Compare( "ox", "öa", true, System.Globalization.CultureInfo.CurrentCulture); 等价于string.Compare( "ox", "oea", true, System.Globalization.CultureInfo.CurrentCulture);。那么结果 1 是有道理的。

【讨论】:

  • 好的,谢谢。但接下来的问题是对列表进行排序。在第一个字符处使用 o 和 ö 比较混合条目的结果。 CompareOrdinal 和特殊字符位于列表末尾。我需要的是一个列表,首先是所有 o,然后是所有 ö...
  • @Udo 你能否用输入数据示例和预期结果更新你的问题,以便更容易理解你的意思?!
  • @Useme Alehosaini。我添加了一个示例。
猜你喜欢
  • 2019-10-26
  • 2011-09-18
  • 2012-03-09
  • 1970-01-01
  • 2012-05-12
  • 2011-04-07
  • 2010-10-14
相关资源
最近更新 更多