共用方式為


比較和排序特定文化特性的資料

更新:2007 年 11 月

不同的文化特性使用不同的排列項目的字母順序和慣例。例如,排序次序可以是區分大小寫或者不區分大小寫。排序次序可以根據注音或根據字元的外觀。在東亞語系中,排序次序可依筆劃和文字字根進行。排序次序同時也視語言和文化特性使用的字母基礎順序而定。例如,瑞典文的 "Æ" 字元的字母排列在 "Z" 之後。德文也使用這個字元,但它的排序次序類似 "ae",其字母排列位於字母 "A" 之後。為支援特定文化特性和特性語言排序慣例,世界性的應用程式必須能夠根據個別的文化特性來比較和排序資料。

注意:在有些案例中,區分文化特性的行為並不適合。如需執行不區分文化特性作業之時機和方式的詳細資訊,請參閱不區分文化特性的字串作業

比較字串

CompareInfo 類別提供可用來執行區分文化特性字串比較的方法集。CultureInfo 類別有 CompareInfo 屬性,這是此類別的執行個體。這個屬性定義比較和排序特定文化特性字串的方法。Compare() 方法會使用 CompareInfo 屬性中的資訊來比較字串。如果 string1 小於 string2,String.Compare 方法將傳回負整數,如果 string1 和 string2 相等,將傳回零 (0),如果 string1 大於 string2,將傳回正整數。

下列程式碼範例示範根據用來執行比較的文化特性,String.Compare 方法評估這兩個字串的方式有何不同。首先,CurrentCulture 會設為丹麥文 (丹麥),並比較字串 "Apple" 和 "Æble"。丹麥文會將字元 "Æ" 視為單一字母,其字母排列位於字母 "Z" 之後。因此,在丹麥文化特性中,字串 "Æble" 大於 "Apple"。接著,CurrentCulture 會設為英文 (美國),並再一次比較字串 "Apple" 和 "Æble"。這一次,字串 "Æble" 即被判斷為小於 "Apple"。英文會將字元 "Æ" 視為特殊符號,其字母排列位於字母 "A" 之前。

Imports System
Imports System.Globalization
Imports System.Threading
Imports Microsoft.VisualBasic

Public Class TestClass
   Public Shared Sub Main()
      Dim str1 As String = "Apple"
      Dim str2 As String = "Æble"
      
      ' Sets the CurrentCulture to Danish in Denmark.
      Thread.CurrentThread.CurrentCulture = New CultureInfo("da-DK")
      Dim result1 As Integer = [String].Compare(str1, str2)
      Console.WriteLine(ControlChars.Newline + "When the CurrentCulture _
         is ""da-DK""," + ControlChars.Newline + " the result of _
         comparing_{0} with {1} is: {2}", str1, str2, result1)
      
      ' Sets the CurrentCulture to English in the U.S.
      Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
      Dim result2 As Integer = [String].Compare(str1, str2)
      Console.WriteLine(ControlChars.Newline + "When the _
         CurrentCulture is""en-US""," + ControlChars.Newline + " _
         the result of comparing {0} with {1} is: {2}", str1, _
         str2,result2)
   End Sub
End Class
using System;
using System.Globalization;
using System.Threading;

public class CompareStringSample
{
   public static void Main()
   {
      string str1 = "Apple";
      string str2 = "Æble"; 

      // Sets the CurrentCulture to Danish in Denmark.
      Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
      // Compares the two strings.
      int result1 = String.Compare(str1, str2);
      Console.WriteLine("\nWhen the CurrentCulture is \"da-DK\",\nthe 
            result of comparing {0} with {1} is: {2}",str1, str2, 
            result1);

      // Sets the CurrentCulture to English in the U.S.
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
      // Compares the two strings.
      int result2 = String.Compare(str1, str2);
      Console.WriteLine("\nWhen the CurrentCulture is \"en-US\",\nthe 
            result of comparing {0} with {1} is: {2}",str1, str2, 
            result2);
   }
}

如果您執行這個程式碼,它將產生下列輸出:

When the CurrentCulture is "da-DK", 
the result of comparing Apple with Æble is: -1

When the CurrentCulture is "en-US", 
the result of comparing Apple with Æble is: 1

如需比較字串的詳細資訊,請參閱比較字串

使用替代排序次序

有些文化特性支援一個以上的排序次序。例如,文化特性 zh-CN (中國的中文) 支援發音排序 (預設) 和筆劃排序。當您的應用程式使用文化特性名稱 (例如 "zh-CN") 建立 CultureInfo 物件時,將使用預設的排序次序。如果要指定替代排序次序,應用程式應使用替代排序次序的 LCID 來建立 CultureInfo 物件。接著,應用程式應該從 CompareInfo 取得 CompareInfo 物件以用於字串比較。或者,您的應用程式也可以直接使用 GetCompareInfo() 建立 CompareInfo 物件,指定地區設定識別項 (LCID) 做為替代的排序次序。

下表列出支援替代排序次序的文化特性清單,以及預設和替代排序次序的 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

搜尋字串

您的應用程式可以使用多載的 IndexOf() 方法來擷取指定字串中字元或子字串的以零起始索引。如果指定的字串中找不到字元或子字串,該方法將擷取負整數。使用 CompareInfo.IndexOf 搜尋指定的字元時,應用程式應注意接受 CompareOptions 參數的方法多載所執行的比較,與不接受這個參數的方法多載不同。搜尋字元型別且不接受 CompareOptions 參數的方法多載將執行區分文化特性的搜尋。這表示如果 Unicode 值代表的是預先組成的字元,例如連字 "Æ" (\u00C6),視文化特性而定,只要其組成元件以正確序列出現,就可能視為相等,例如 "AE" (\u0041\u0045)。若要執行序數 (不區分文化特性) 搜尋,也就是只有在 Unicode 值相同時,字元型別才會視為等於另一個字元型別,則應用程式應使用其中一個接受 CompareOptions 參數並將參數設為 Ordinal 值的 CompareInfo.IndexOf 多載。

您的應用程式也可以使用搜尋字元的 IndexOf() 方法多載,來執行序數 (不區分文化特性) 搜尋。請注意,此方法搜尋字串的多載會執行區分文化特性的搜尋。

下列程式碼範例示範根據文化特性,IndexOf 方法擷取的不同結果。CultureInfo 物件會為指定為 "da-DK" 的丹麥文 (丹麥) 建立。接著,會使用 CompareInfo.IndexOf 方法的多載,在字串 "Æble" 和 "aeble" 中搜尋字元 "Æ"。請注意,在 "da-DK" 文化特性中,接受設為 Ordinal 之 CompareOptions 參數的 CompareInfo.IndexOf 方法,與不接受這個參數的相同方法,會擷取相同的結果。字元 "Æ" 只會視為等同於 Unicode 字碼值 \u00E6。

Imports System
Imports System.Globalization
Imports System.Threading
Imports Microsoft.VisualBasic

Public Class CompareClass
   Public Shared Sub Main()
      Dim str1 As String = "Æble"
      Dim str2 As String = "aeble"
      Dim find As Char = "Æ"
      
      ' Creates a CultureInfo for Danish in Denmark.
      Dim ci As New CultureInfo("da-DK")
      
      Dim result1 As Integer = ci.CompareInfo.IndexOf(str1, find)
      Dim result2 As Integer = ci.CompareInfo.IndexOf(str2, find)
      Dim result3 As Integer = ci.CompareInfo.IndexOf(str1, find, _ 
         CompareOptions.Ordinal)
      Dim result4 As Integer = ci.CompareInfo.IndexOf(str2, find, _
         CompareOptions.Ordinal)      
      
      Console.WriteLine(ControlChars.Newline + "CultureInfo is set to _
         {0}", ci.DisplayName)
      Console.WriteLine(ControlChars.Newline + "Using _
         CompareInfo.IndexOf(string, char) method" + _
         ControlChars.Newline + " the result of searching for {0} in the _
         string {1} is: {2}", find, str1, result1)
      Console.WriteLine(ControlChars.Newline + "Using _
         CompareInfo.IndexOf(string, char) method" + _
         ControlChars.Newline + " the result of searching for {0} in the _
         string {1} is: {2}", find, str2, result2)
      Console.WriteLine(ControlChars.Newline + "Using _
         CompareInfo.IndexOf(string, char, CompareOptions) method" + _
         ControlChars.Newline + " the result of searching for {0} in the _
         string {1} is: {2}", find, str1, result3)
      Console.WriteLine(ControlChars.Newline + "Using _
         CompareInfo.IndexOf(string, char, CompareOptions) method" + _
         ControlChars.Newline + " the result of searching for {0} in the _
         string {1} is: {2}", find, str2, result4)
   End Sub
End Class
using System;
using System.Globalization;
using System.Threading;

public class CompareClass
{

   public static void Main()
   {
      string str1 = "Æble";
      string str2 = "aeble"; 
      char find = 'Æ';

      // Creates a CultureInfo for Danish in Denmark.
      CultureInfo ci= new CultureInfo("da-DK");

      int result1 = ci.CompareInfo.IndexOf(str1, find);
      int result2 = ci.CompareInfo.IndexOf(str2, find);
      int result3 = ci.CompareInfo.IndexOf(str1, find,   
         CompareOptions.Ordinal);
      int result4 = ci.CompareInfo.IndexOf(str2, find, 
         CompareOptions.Ordinal);

      Console.WriteLine("\nCultureInfo is set to {0} ", ci.DisplayName);
      Console.WriteLine("\nUsing CompareInfo.IndexOf(string, char) 
         method\nthe result of searching for {0} in the string {1} is: 
         {2}", find, str1, result1);
      Console.WriteLine("\nUsing CompareInfo.IndexOf(string, char) 
         method\nthe result of searching for {0} in the string {1} is: 
         {2}", find, str2, result2);
      Console.WriteLine("\nUsing CompareInfo.IndexOf(string, char, 
         CompareOptions) method\nthe result of searching for {0} in the 
         string {1} is: {2}", find, str1, result3);
      Console.WriteLine("\nUsing CompareInfo.IndexOf(string, char, 
         CompareOptions) method\nthe result of searching for {0} in the 
         string {1} is: {2}", find, str2, result4);
   }
}

這個程式碼產生下列輸出:

CultureInfo is set to Danish (Denmark) 

Using CompareInfo.IndexOf(string, char) method
the result of searching for Æ in the string Æble is: 0

Using CompareInfo.IndexOf(string, char) method
the result of searching for Æ in the string aeble is: -1

Using CompareInfo.IndexOf(string, char, CompareOptions) method
the result of searching for Æ in the string Æble is: 0

Using CompareInfo.IndexOf(string, char, CompareOptions) method
the result of searching for Æ in the string aeble is: -1

如果您的應用程式使用 CultureInfo ci = new CultureInfo ("en-US") 取代 CultureInfo ci = new CultureInfo ("da-DK"),則使用設為 Ordinal 之CompareOptions 參數的 IndexOf() 方法和不使用這個參數的相同方法,將擷取不同的結果。由 IndexOf 方法執行的區分文化特性比較,會將字元 "Æ" 評估為與其元件 "ae" 完全相同。由 IndexOf 方法執行的序數 (不區分文化特性) 比較,不會擷取等同於 "ae" 的字元 "Æ",因為其 Unicode 字碼的值不相符。

當您重新編譯和執行英文 (美國) "en-US" 文化特性的程式碼時,將產生下列輸出:

The CurrentCulture property is set to English (United States) 

Using CompareInfo.IndexOf(string, char) method
the result of searching for Æ in the string Æble is: 0

Using CompareInfo.IndexOf(string, char) method
the result of searching for Æ in the string aeble is: 0

Using CompareInfo.IndexOf(string, char, CompareOptions) method
the result of searching for Æ in the string Æble is: 0

Using CompareInfo.IndexOf(string, char, CompareOptions) method
the result of searching for Æ in the string aeble is: -1

排序字串

Array 類別提供多載的 Sort() 方法,可讓您的應用程式根據 CurrentCulture 屬性排序陣列。在下列範例中,將建立由三個字串組成的陣列。首先,CurrentCulture 屬性會設為英文 (美國) "en-US",而且會呼叫 Sort() 方法。產生的排序次序將使用英文 (美國) 文化特性的排序慣例做為依據。接著,CurrentCulture 屬性會設為丹麥文 (丹麥) "da-DK",並再次呼叫 Array.Sort 方法。由於使用了為 "da-DK" 文化特性的排序慣例,因此請注意產生的排序次序與 "en-US" 結果有何不同之處。

Imports System
Imports System.Threading
Imports System.IO
Imports System.Globalization
Imports Microsoft.VisualBasic

Public Class TextToFile   
   Public Shared Sub Main()
      Dim str1 As [String] = "Apple"
      Dim str2 As [String] = "Æble"
      Dim str3 As [String] = "Zebra"
      
      ' Creates and initializes a new Array to store 
      ' these date/time objects.
      Dim stringArray As Array = Array.CreateInstance(GetType([String]), _
         3)
      stringArray.SetValue(str1, 0)
      stringArray.SetValue(str2, 1)
      stringArray.SetValue(str3, 2)
      
      ' Displays the values of the Array.
      Console.WriteLine(ControlChars.Newline + "The Array initially _
         contains the following strings:")
      PrintIndexAndValues(stringArray)
      
      ' Sets the CurrentCulture to "en-US".
      Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
      ' Sorts the values of the Array.
      Array.Sort(stringArray)
      
      ' Displays the values of the Array.
      Console.WriteLine(ControlChars.Newline + "After sorting for the _
         culture ""en-US"":")
      PrintIndexAndValues(stringArray)
      
      ' Sets the CurrentCulture to "da-DK".
      Thread.CurrentThread.CurrentCulture = New CultureInfo("da-DK")
      ' Sort the values of the Array.
      Array.Sort(stringArray)
      
      ' Displays the values of the Array.
      Console.WriteLine(ControlChars.Newline + "After sorting for the _
         culture ""da-DK"":")
      PrintIndexAndValues(stringArray)
   End Sub

   Public Shared Sub PrintIndexAndValues(myArray As Array)
      Dim i As Integer
      For i = myArray.GetLowerBound(0) To myArray.GetUpperBound(0)
         Console.WriteLine(ControlChars.Tab + "[{0}]:" + _
            ControlChars.Tab + "{1}", i, myArray.GetValue(i))
      Next i
   End Sub 
End Class
using System;
using System.Threading;
using System.Globalization;

public class ArraySort 
{
   public static void Main(String[] args) 
   {
      String str1 = "Apple";
      String str2 = "Æble";
      String str3 = "Zebra";

      // Creates and initializes a new Array to store the strings.
      Array stringArray = Array.CreateInstance( typeof(String), 3 );
      stringArray.SetValue(str1, 0 );
      stringArray.SetValue(str2, 1 );
      stringArray.SetValue(str3, 2 );

      // Displays the values of the Array.
      Console.WriteLine( "\nThe Array initially contains the following 
            strings:" );
      PrintIndexAndValues(stringArray);

      // Sets the CurrentCulture to "en-US".
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
      // Sort the values of the Array.
      Array.Sort(stringArray);

      // Displays the values of the Array.
      Console.WriteLine( "\nAfter sorting for the culture \"en-US\":" );
      PrintIndexAndValues(stringArray); 

      // Sets the CurrentCulture to "da-DK".
      Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
      // Sort the values of the Array.
      Array.Sort(stringArray);

      // Displays the values of the Array.
      Console.WriteLine( "\nAfter sorting for the culture \"da-DK\":" );
      PrintIndexAndValues(stringArray); 
   }
   public static void PrintIndexAndValues(Array myArray)  
   {
      for ( int i = myArray.GetLowerBound(0); i <= 
            myArray.GetUpperBound(0); i++ )
      Console.WriteLine( "\t[{0}]:\t{1}", i, myArray.GetValue( i ) );
   }
}

這個程式碼產生下列輸出:

The Array initially contains the following strings:
   [0]:   Apple
   [1]:   Æble
   [2]:   Zebra

After sorting for the culture "en-US":
   [0]:   Æble
   [1]:   Apple
   [2]:   Zebra

After sorting for the culture "da-DK":
   [0]:   Apple
   [1]:   Zebra
   [2]:   Æble

使用排序鍵

排序鍵將用來支援區分文化特性的排序作業。根據 Unicode Standard,字串的每個字元都指定有數種排序權重,其中包括字母、大小寫和變音符號權重。排序鍵可以當做特定字串的這些權重的存放庫。例如,排序鍵可能含有字母權重字串,之後並跟隨大小寫權重字串等等。如需排序鍵概念的詳細資訊,請參閱<Unicode Standard>,網址為 www.unicode.org。

在 .NET Framework 中,SortKey 類別會將字串對應到其排序鍵 (反之亦然)。您的應用程式可以使用 GetSortKey() 方法為您指定的字串建立排序鍵。指定的字串所產生的排序鍵是位元組序列,該位元組序列將視 CurrentCulture 和指定的 CompareOptions 值而有所不同。例如,如果應用程式在建立排序鍵時指定 IgnoreCase 這個值,使用該排序鍵的字串比較作業會忽略大小寫。

在建立字串的排序鍵之後,應用程式可以將它當做參數傳遞給 SortKey 類別提供的方法。Compare 方法可用來比較排序鍵。由於這個方法會執行簡單的位元組逐一比較,因此速度要比使用 Compare() 快得多。在時常用到排序功能的應用程式中,可以為使用到的所有字串產生並儲存排序鍵,藉以提高效能。如果需要使用排序或比較作業,應用程式就可以使用排序鍵,而不是字串。

下列程式碼範例會在 CurrentCulture 設為 "da-DK" 時建立兩個字串的排序鍵。它將使用 SortKey.Compare 方法來比較這兩個字串,並且顯示其結果。如果 string1 小於 string2,方法將傳回負整數,如果 string1 和 string2 相等,將傳回零 (0),如果 string1 大於 string2,將傳回正整數。接著,CurrentCulture 屬性將設為 "en-US",同時為相同的字串建立排序鍵。然後比較字串的排序鍵和顯示其結果。請注意,排序的結果將依據 CurrentCulture 的設定而有所不同。雖然下列程式碼範例的結果和這個主題稍早之前出現的比較字串範例結果完全相同,但是使用 SortKey.Compare 方法比使用 String.Compare 方法的速度更快。

Imports System
Imports System.Threading
Imports System.Globalization
Imports Microsoft.VisualBasic

Public Class SortKeySample
   Public Shared Sub Main()
      Dim str1 As [String] = "Apple"
      Dim str2 As [String] = "Æble"
      
      ' Sets the CurrentCulture to "da-DK".
      Dim dk As New CultureInfo("da-DK")
      Thread.CurrentThread.CurrentCulture = dk
      
      ' Creates a culturally sensitive sort key for str1.
      Dim sc1 As SortKey = dk.CompareInfo.GetSortKey(str1)
      ' Create a culturally sensitive sort key for str2.
      Dim sc2 As SortKey = dk.CompareInfo.GetSortKey(str2)
      
      ' Compares the two sort keys and display the results.
      Dim result1 As Integer = SortKey.Compare(sc1, sc2)
      Console.WriteLine(ControlChars.Newline + "When the CurrentCulture _
         is ""da-DK""," + ControlChars.Newline + " the result of _
         comparing {0} with {1} is: {2}", str1, str2, result1)
      
      ' Sets the CurrentCulture to "en-US".
      Dim enus As New CultureInfo("en-US")
      Thread.CurrentThread.CurrentCulture = enus
      
      ' Creates a culturally sensitive sort key for str1.
      Dim sc3 As SortKey = enus.CompareInfo.GetSortKey(str1)
      ' Create a culturally sensitive sort key for str1.
      Dim sc4 As SortKey = enus.CompareInfo.GetSortKey(str2)
      
      ' Compares the two sort keys and display the results.
      Dim result2 As Integer = SortKey.Compare(sc3, sc4)
      Console.WriteLine(ControlChars.Newline + "When the CurrentCulture _
         is ""en-US""," + ControlChars.Newline + " the result of _
         comparing {0} with {1} is: {2}", str1, str2, result2)
   End Sub
End Class
using System;
using System.Threading;
using System.Globalization;

public class SortKeySample 
{
   public static void Main(String[] args) 
   {
      String str1 = "Apple";
      String str2 = "Æble";

      // Sets the CurrentCulture to "da-DK".
      CultureInfo dk = new CultureInfo("da-DK");
      Thread.CurrentThread.CurrentCulture = dk;

      // Creates a culturally sensitive sort key for str1.
      SortKey sc1 = dk.CompareInfo.GetSortKey(str1);
      // Create a culturally sensitive sort key for str2.
      SortKey sc2 = dk.CompareInfo.GetSortKey(str2);

      // Compares the two sort keys and display the results.
      int result1 = SortKey.Compare(sc1, sc2);
      Console.WriteLine("\nWhen the CurrentCulture is \"da-DK\",\nthe 
            result of comparing {0} with {1} is: {2}", str1, str2, 
            result1);

      // Sets the CurrentCulture to "en-US".
      CultureInfo enus = new CultureInfo("en-US");
      Thread.CurrentThread.CurrentCulture = enus ;

      // Creates a culturally sensitive sort key for str1.
      SortKey sc3 = enus.CompareInfo.GetSortKey(str1);
      // Create a culturally sensitive sort key for str1.
      SortKey sc4 = enus.CompareInfo.GetSortKey(str2);

      // Compares the two sort keys and display the results.
      int result2 = SortKey.Compare(sc3, sc4);
      Console.WriteLine("\nWhen the CurrentCulture is \"en-US\",\nthe 
            result of comparing {0} with {1} is: {2}", str1, str2, 
            result2);
   }
}

這個程式碼產生下列輸出:

When the CurrentCulture is "da-DK", 
the result of comparing Apple with Æble is: -1

When the CurrentCulture is "en-US", 
the result of comparing Apple with Æble is: 1

正規化

您的應用程式可以在排序之前將字串正規化為大寫或小寫。字串排序和大小寫的規則是特定的語言。例如,即使是在以拉丁文指令碼為基礎的語言中,也會有不同的撰寫和排序規則。只有少數的語言 (包括英文) 的排序次序是與字碼指標的次序相符,例如 A [65] 在 B [66] 之前。

您的應用程式不應使用字碼指標來執行精準的排序和字串比較。此外,.NET Framework 不會強迫或保證指定的正規化格式您應該在您所開發的應用程式中執行適合的正規化作業。

如需字串正規化的詳細資訊,請參閱正規化和排序

請參閱

概念

不區分文化特性的字串作業

正規化和排序

其他資源

編碼和當地語系化