全球化(5):排序和字符串比较

      在全球化的需求中,不同区域的用户可能对“排序”列表有完全不同德期望。不同语言之间不仅字母顺序不同,而且字典和电话簿中的项目排序约定也可能大相径庭。例如,在瑞典语中,一些带重音符号的元音排在 "Z" 之后,而在其他一些欧洲国家/地区中,同样带有重音符号的元音却紧跟在不带音调符号的元音之后。包括非拉丁语脚本字符的语言具有一些特殊的排序规则。亚洲语言可按拼音、部首顺序、笔画数等多种方式进行排序。字符串的排序和比较是特定于语言的。即使在基于拉丁语脚本的语言中,也有不同的构成和排序规则。因此,在进行排序和字符串比较时,依靠的并不是码点。

     .NET中的字符串比较

     CompareInfo类提供了一组可用来执行区分文化的字符串比较方法。CultureInfo.CompareInfo属性CultureInfo 类的一个实例)可定义如何针对特定文化来比较和排序字符串。String.Compare方法使用CultureInfo.CompareInfo 属性中的信息来比较字符串。如果 string1 小于 string2,此方法返回一个负整数;如果 string1 和 string2 相等,则返回零 (0);如果 string1 大于 string2,则返回一个正整数。

 1:  using System;
 2:  using System.Globalization;
 3:  using System.Threading;
 4:   
 5:  class Program
 6:  {
 7:      static void Main(string[] args)
 8:      {
 9:          string str1 = "Apple";
10:          string str2 = "Æble";
11:   
12:          Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
13:          Console.WriteLine(String.Compare(str1, str2));
14:   
15:          Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
16:          Console.WriteLine(String.Compare(str1, str2));
17:   
18:          Console.ReadLine();
19:      }
20:  }
21:   

      以上代码示例将说明如何根据进行比较时所使用的文化,通过 String.Compare 方法以不同的方式来计算两个字符串。首先,将 CurrentCulture 设置为丹麦语(丹麦),并比较字符串 "Apple" 和 "Æble"。丹麦语将字符 "Æ" 视为一个单独的字母,在字母表中将其排在 "Z" 之后。因此对于丹麦语文化,字符串 "Æble" 大于 "Apple"。接下来,将 CurrentCulture 设置为英语(美国),再次比较字符串 "Apple" 和 "Æble"。这一次,字符串 "Æble" 被认为小于 "Apple"。英语语言将字符 "Æ" 视为一个特殊符号,在字母表中将其排在字母 "A" 之前。

       运行结果:

      image

 

      替代字符串排序

      一些文化可支持多种排序顺序。例如,文化 "zh-CN"(中国中文)支持按发音(默认)和按笔画数排序。使用文化名称(如 "zh-CN")创建 CultureInfo 对象时,将使用默认排序顺序。要指定替代排序顺序,请使用替代排序顺序的 LCID 创建一个 CultureInfo 对象。然后,从 CultureInfo.CompareInf 获取一个 CompareInfo 对象以用于字符串比较。或者,也可以使用 CompareInfo.GetCompareInfo 方法 (Int32) 并指定替代排序顺序的 LCID 来直接创建一个 CompareInfo 对象。

 

    支持替代排序顺序的文化以及用于默认和替代排序顺序的 LCID:

区域性名称语言 - 国家/地区默认排序名称和 LCID替换排序名称和 LCID

es-ES

西班牙语 - 西班牙

国际:0x00000C0A

传统:0x0000040A

zh-TW

中文 - 台湾

笔画数:0x00000404

注音符号:0x00030404

zh-CN

中文 - 中国

发音:0x00000804

笔画数:0x00020804

zh-HK

中文 - 香港特别行政区

笔画数:0x00000c04

笔画数:0x00020c04

zh-SG

中文 - 新加坡

发音:0x00001004

笔画数:0x00021004

zh-MO

中文 - 澳门特别行政区

发音:0x00001404

笔画数:0x00021404

ja-JP

日语 - 日本

默认:0x00000411

Unicode:0x00010411

ko-KR

朝鲜语 - 韩国

默认:0x00000412

朝鲜语 Xwansung - Unicode:0x00010412

de-DE

德语 - 德国

词典:0x00000407

电话簿排序 DIN:0x00010407

hu-HU

匈牙利语 - 匈牙利

默认:0x0000040e

技术排序:0x0001040e

ka-GE

格鲁吉亚语 - 格鲁吉亚

传统:0x00000437

现代排序:0x00010437

 

      中文默认拼音排序:

 1:  using System;
 2:  using System.Globalization;
 3:  using System.Threading;
 4:  using System.Collections;
 5:  using System.Collections.Generic;
 6:   
 7:  class Program
 8:  {
 9:      static void Main(string[] args)
10:      {
11:          //默认拼音LCID:0x00000804
12:          Thread.CurrentThread.CurrentCulture = new CultureInfo(2052);
13:          SortedList<string,string> MyList = new SortedList<string,string>();
14:          MyList.Add("一(yi)", "data1");
15:          MyList.Add("二(er)", "data2");
16:          MyList.Add("三(san)", "data3");
17:   
18:          foreach(KeyValuePair<string, string> kvp in MyList )
19:          {
20:              Console.WriteLine("{0} is {1}", kvp.Key, kvp.Value);
21:          }
22:   
23:          Console.ReadLine();
24:      }
25:  }
26:   
27:   

      结果:

     image

      中文笔画排序:

 1:  using System;
 2:  using System.Globalization;
 3:  using System.Threading;
 4:  using System.Collections;
 5:  using System.Collections.Generic;
 6:   
 7:  class Program
 8:  {
 9:      static void Main(string[] args)
10:      {
11:          //笔画排序LCID:0x00020804
12:          Thread.CurrentThread.CurrentCulture = new CultureInfo(0x00020804);
13:          SortedList<string,string> MyList = new SortedList<string,string>();
14:          MyList.Add("一(yi)", "data1");
15:          MyList.Add("二(er)", "data2");
16:          MyList.Add("三(san)", "data3");
17:   
18:          foreach(KeyValuePair<string, string> kvp in MyList )
19:          {
20:              Console.WriteLine("{0} is {1}", kvp.Key, kvp.Value);
21:          }
22:   
23:          Console.ReadLine();
24:      }
25:  }
26:   

      结果:

     image

     可以用name为zh-CN_Stroke代替0x00020804:

1:  Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN_Stroke");

 

      字符串排序

      Array 类提供了一个重载的Array.Sort方法,通过它可以根据 Thread.CurrentThread.CurrentCulture 属性来排序数据。

 

 

 

 

 1:  using System;
 2:  using System.Globalization;
 3:  using System.Threading;
 4:  using System.Collections;
 5:   
 6:  class Program
 7:  {
 8:      static void Main(string[] args)
 9:      {
10:          string str1 = "三";
11:          string str2 = "二";
12:          string str3 = "一";
13:   
14:          Array stringArray = Array.CreateInstance(typeof(String), 3);
15:          stringArray.SetValue(str1, 0);
16:          stringArray.SetValue(str2, 1);
17:          stringArray.SetValue(str3, 2);
18:   
19:          Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN");
20:          Console.WriteLine("Default zh-CN:");
21:          Array.Sort(stringArray);
22:          PrintIndexAndValues(stringArray);
23:   
24:          Console.ReadLine();
25:      }
26:   
27:      public static void PrintIndexAndValues(Array myArray)
28:      {
29:          for (int i = myArray.GetLowerBound(0);
30:          i <= myArray.GetUpperBound(0); i++)
31:              Console.WriteLine("\t[{0}]:\t{1}", i, myArray.GetValue(i));
32:      }
33:  }

      默认中文拼音排序:

     image

 1:  using System;
 2:  using System.Globalization;
 3:  using System.Threading;
 4:  using System.Collections;
 5:  using System.Collections.Generic;
 6:   
 7:  class Program
 8:  {
 9:      static void Main(string[] args)
10:      {
11:          string str1 = "三";
12:          string str2 = "二";
13:          string str3 = "一";
14:   
15:          Array stringArray = Array.CreateInstance(typeof(String), 3);
16:          stringArray.SetValue(str1, 0);
17:          stringArray.SetValue(str2, 1);
18:          stringArray.SetValue(str3, 2);
19:   
20:          Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN_Stroke");
21:          Console.WriteLine("zh-CN Stroke:");
22:          Array.Sort(stringArray);
23:          PrintIndexAndValues(stringArray);
24:   
25:          Console.ReadLine();
26:      }
27:   
28:      public static void PrintIndexAndValues(Array myArray)
29:      {
30:          for (int i = myArray.GetLowerBound(0);
31:          i <= myArray.GetUpperBound(0); i++)
32:              Console.WriteLine("\t[{0}]:\t{1}", i, myArray.GetValue(i));
33:      }
34:  }
35:   

      中文笔画排序:   

     image

 

      使用排序关键字

      根据排序关键字方法,字符串中的每个字符都被赋予了多个类别的排序权重,包括字母、大小写和音调符号权重等。对于特定字符串,排序关键字可作为这些权重的存储库。例如,某个排序关键字可能依次包含一串字母权重、一串大小写权重等等。在.NET Framework 中,SortKey类将字符串映射到其排序关键字,反之亦然。您可以使用CompareInfo.GetSortKey方法为指定的字符串创建排序关键字。针对指定字符串生成的排序关键字是一个字节序列,它会根据您指定的 CurrentCulture 和 CompareOptions 的不同而变化。例如,如果在创建排序关键字时指定了 IgnoreCase,则使用此排序关键字进行字符串比较时将忽略大小写。为字符串创建了排序关键字之后,可以将其作为参数传递给 SortKey 类所提供的方法。SortKey.Compare方法允许您对排序关键字进行比较。由于 SortKey.Compare 执行的是简单的逐字节比较,因此它比使用String.Compare 要快很多。在用于排序的应用程序中,通过生成应用程序使用的所有字符串的排序关键字并将其存储下来,可以改进应用程序的性能。当需要进行排序或比较操作时,可以使用排序关键字而不是字符串。

 1:  using System;
 2:  using System.Globalization;
 3:  using System.Threading;
 4:   
 5:  class Program
 6:  {
 7:      static void Main(string[] args)
 8:      {
 9:          string str1 = "Apple";
10:          string str2 = "Æble";
11:   
12:          CultureInfo dk = new CultureInfo("da-DK");
13:          Thread.CurrentThread.CurrentCulture = dk;
14:   
15:          SortKey sc1 = dk.CompareInfo.GetSortKey(str1);
16:          SortKey sc2 = dk.CompareInfo.GetSortKey(str2);
17:   
18:          Console.WriteLine(SortKey.Compare(sc1, sc2));
19:   
20:          CultureInfo enus = new CultureInfo("en-US");
21:          Thread.CurrentThread.CurrentCulture = enus;
22:   
23:          SortKey sc3 = enus.CompareInfo.GetSortKey(str1);
24:          SortKey sc4 = enus.CompareInfo.GetSortKey(str2);
25:   
26:          Console.WriteLine(SortKey.Compare(sc3, sc4));
27:   
28:          Console.ReadLine();
29:      }
30:  }
31:   

       结果:

      image

posted @ 2010-12-13 23:18  Asharp  阅读(2167)  评论(1编辑  收藏  举报