Сравнение и сортировка данных для конкретного языка и региона
В различных культурных средах используются разные соглашения для установления последовательности элементов и алфавитного порядка. Например, порядок сортировки может зависеть или не зависеть от регистра символов. Он может быть основан на произношении символов или на их виде. В языках Восточной Азии порядок сортировки определяется штрихами и корнями идеограмм. Порядок сортировки также может изменяться в зависимости от основного порядка для алфавита в определенном языке (культурной среде). Например, в шведском языке есть символ "Æ", который в алфавите следует за буквой "Z". В немецком языке тоже есть этот символ, но он обозначается как "ae" и идет в алфавите после "A". Международные приложения должны поддерживать сравнениеи сортировку данных в зависимости правил характерных для конкретоного языка и региона.
Примечание В некоторых случаях зависимость от языка и региона нежелательна. Дополнительные сведения о том, когда и как проводить операции, не зависящие от языка и региона, см. в разделе Строковые операции, не зависящие от языка и региона.
Сравнение строк
Класс CompareInfo предоставляет набор методов для сравнения строк, зависящих от языка и региона. Класс CultureInfo обладает свойством CompareInfo, которое является экземпляром этого класса. Это свойство определяет порядок сравнения и сортировки строк для конкретного языка и региона. Метод String.Compare использует данные, хранящиеся в свойстве CompareInfo, для сравнения строк. Метод String.Compare возвращает отрицательное целое число, если string1 меньше, чем string2, ноль, если string1 и string2 равны, или положительное целое число, если string1 больше, чем string2.
В следующем примере кода показаны различные способы обработки двух строк с помощью метода String.Compare в зависимости от языка и региона, используемых при сравнении. Сначала свойству CurrentCulture присваивается значение da-DK для "Датский (Дания)", после чего выполняется сравнение строк "Apple" и "Æble". В датском языке символ "Æ" рассматривается как отдельная буква и стоит в алфавите после буквы "Z". Поэтому с региональным параметром "Дания" строка "Æble" считается больше, чем строка "Apple". Далее свойству CurrentCulture присваивается значение en-US для "Английский (США)", после чего снова выполняется сравнение строк "Apple" и "Æble". В этом случае строка "Æble" меньше, чем строка "Apple". В английском языке символ "Æ" рассматривается как специальный символ и стоит в алфавите перед буквой "A".
Imports System.Globalization
Imports System.Threading
Public Class TestClass
Public Shared Sub Main()
Dim str1 As String = "Apple"
Dim str2 As String = "Æble"
' Set the current culture to Danish in Denmark.
Thread.CurrentThread.CurrentCulture = New CultureInfo("da-DK")
Dim result1 As Integer = [String].Compare(str1, str2)
Console.WriteLine("When the CurrentCulture is ""da-DK"",")
Console.WriteLine("the result of comparing_{0} with {1} is: {2}",
str1, str2, result1)
' Set the current culture to English in the U.S.
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
Dim result2 As Integer = [String].Compare(str1, str2)
Console.WriteLine("When the CurrentCulture is""en-US"",")
Console.WriteLine("the result of comparing {0} with {1} is: {2}",
str1, str2,result2)
End Sub
End Class
' The example displays the following output:
' 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
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);
}
}
// The example displays the following output:
// 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" китайский (КНР) поддерживается сортировка по произношению (по умолчанию) и сортировка по числу штрихов. При создании объекта CultureInfo с использованием имени языка и региональных параметров, например "zh-CN", применяется порядок сортировки по умолчанию. Для выбора альтернативного порядка сортировки в приложении необходимо создать объект CultureInfo с указанием идентификатора альтернативного порядка сортировки. Затем необходимо получить объект CompareInfo из свойства CompareInfo, который будет использоваться для сравнения строк. Также приложение может создать объект CompareInfo непосредственно с помощью метода CompareInfo.GetCompareInfo, указав идентификатор для альтернативного порядка сортировки.
В приведенной ниже таблице перечислены языки и региональные параметры, в которых поддерживается альтернативный порядок сортировки, и идентификаторы для порядка сортировки по умолчанию и альтернативного порядка сортировки.
Название языка и региональных параметров |
Язык и региональные параметры |
Название и идентификатор для типа сортировки по умолчанию |
Название и идентификатор для альтернативного типа сортировки |
---|---|---|---|
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 |
Юникод: 0x00010411 |
ko-KR |
Корейский (Корея) |
По умолчанию: 0x00000412 |
Корейский Xwansung – Юникод: 0x00010412 |
de-DE |
Немецкий (Германия) |
Словарь: 0x00000407 |
Сортировка по телефонной книге DIN: 0x00010407 |
hu-HU |
Венгерский (Венгрия) |
По умолчанию: 0x0000040e |
Техническая сортировка: 0x0001040e |
ka-GE |
Грузинский (Грузия) |
Традиционная: 0x00000437 |
Современная сортировка: 0x00010437 |
Поиск строк
В приложении можно использовать перегруженный метод CompareInfo.IndexOf для извлечения индекса символа или подстроки внутри определенной строки. Этот метод возвращает отрицательное целое число, если символ или подстрока не найдены в данной строке. При использовании CompareInfo.IndexOf для поиска определенного символа необходимо учитывать, что перегрузки метода, принимающие параметр CompareOptions, проводят сравнение не так, как перегрузки метода, которые не используют этот параметр. Перегрузки метода, которые выполняют поиск по типу знака и не используют параметр CompareOptions, предназначены для поиска с учетом языка и региона. Если символ является составным знаком Юникод, например лигатурой "Æ" (\u00C6), для некоторых языков и регионов такой символ можно считать эквивалентным любому вхождению его компонентов в правильной последовательности, например "AE" (U+0041, U+0045). Чтобы выполнить поиск по порядковым номерам (без учета языка и региона), при котором один знак считается эквивалентным другому знаку только в том случае, если их значения Юникода совпадают, приложение должно использовать одну из перегрузок CompareInfo.IndexOf, которая принимает параметр CompareOptions и устанавливает для него значение Ordinal.
В приложениях также можно использовать перегрузки метода String.IndexOf, которые выполняют поиск символа для поиска по порядковым номерам (без учета языка и региональных параметров). Необходимо помнить, что перегрузки этого метода, предназначенные для поиска строк, выполняют поиск с учетом культурной среды.
Следующий пример кода показывает разницу между результатами, возвращаемыми методом IndexOf в зависимости от языка и региона. Объект CultureInfo создается для языка и региональных параметров "da-DK" (Датский (Дания)). Далее используется перегрузка метода CompareInfo.IndexOf для поиска символа "Æ" в строках "Æble" и "aeble". Обратите внимание, что для языка и региональных параметров "da-DK" метод CompareInfo.IndexOf, принимающий входной параметр CompareOptions со значением Ordinal, и этот же метод, не использующий данный параметр, возвращают одинаковые результаты. Символ "Æ" считается равным лишь одному символу с кодом Юникода \u00E6.
Imports System.Globalization
Imports System.Threading
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("CultureInfo is set to {0}",
ci.DisplayName)
Console.WriteLine()
Console.WriteLine("Using CompareInfo.IndexOf(string, char) method")
Console.WriteLine("the result of searching for {0} in the string {1} is: {2}",
find, str1, result1)
Console.WriteLine()
Console.WriteLine("Using CompareInfo.IndexOf(string, char) method")
Console.WriteLine("the result of searching for {0} in the string {1} is: {2}",
find, str2, result2)
Console.WriteLine()
Console.WriteLine("Using CompareInfo.IndexOf(string, char, CompareOptions) method")
Console.WriteLine("the result of searching for {0} in the string {1} is: {2}",
find, str1, result3)
Console.WriteLine()
Console.WriteLine("Using CompareInfo.IndexOf(string, char, CompareOptions) method")
Console.WriteLine("the result of searching for {0} in the string {1} is: {2}",
find, str2, result4)
End Sub
End Class
' The example displays the following output:
' 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
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);
}
}
// The example displays the following output:
// 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 ("da-DK") заменяется на CultureInfo ci = new CultureInfo ("en-US"), метод CompareInfo.IndexOf с использованием значения Ordinal параметра CompareOptions и этот же метод, не использующий данный параметр, возвращают различные результаты. При сравнении с учетом языка и региона, производимом при помощи метода CompareInfo.IndexOf, символ "Æ" принимается равным его компонентам "ae". При порядковом (не зависящем от культурной среды) сравнении, производимом при помощи метода CompareInfo.IndexOf, символ "Æ" не возвращается равным "ae", поскольку их кодовые значения Юникода не совпадают.
После перекомпиляции и выполнения этого кода для языка и региональных параметров "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 предоставляет перегруженный метод Array.Sort для сортировки массивов на основании свойства CurrentCulture. В следующем примере создается массив из трех строк. Сначала свойству Thread.CurrentThread.CurrentCulture присваивается значение "en-US", после чего вызывается метод Array.Sort. Полученный в результате порядок сортировки основан на правилах сортировки для языка и региональных параметров Английский (США). Далее свойству Thread.CurrentThread.CurrentCulture присваивается значение "da-DK", после чего повторно вызывается метод Array.Sort. Обратите внимание, что теперь порядок сортировки отличается от результата для языка и региональных параметров "en-US", так как используются правило сортировки данных для "da-DK".
Imports System.Globalization
Imports System.IO
Imports System.Threading
Public Class TextToFile
Public Shared Sub Main()
' Creates and initializes a new array to store
' these date/time objects.
Dim stringArray() As String = { "Apple", "Æble", "Zebra"}
' Displays the values of the array.
Console.WriteLine("The original string array:")
PrintIndexAndValues(stringArray)
' Set the CurrentCulture to "en-US".
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
' Sort the values of the Array.
Array.Sort(stringArray)
' Display the values of the array.
Console.WriteLine("After sorting for the ""en-US"" culture:")
PrintIndexAndValues(stringArray)
' Set 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("After sorting for the culture ""da-DK"":")
PrintIndexAndValues(stringArray)
End Sub
Public Shared Sub PrintIndexAndValues(myArray() As String)
For i As Integer = myArray.GetLowerBound(0) To myArray.GetUpperBound(0)
Console.WriteLine("[{0}]: {1}", i, myArray(i))
Next
Console.WriteLine()
End Sub
End Class
' The example displays the following output:
' The original string array:
' [0]: Apple
' [1]: Æble
' [2]: Zebra
'
' After sorting for the "en-US" culture:
' [0]: Æble
' [1]: Apple
' [2]: Zebra
'
' After sorting for the culture "da-DK":
' [0]: Apple
' [1]: Zebra
' [2]: Æble
using System;
using System.Globalization;
using System.Threading;
public class ArraySort
{
public static void Main(String[] args)
{
// Create and initialize a new array to store the strings.
string[] stringArray = { "Apple", "Æble", "Zebra"};
// Display the values of the array.
Console.WriteLine( "The original string array:");
PrintIndexAndValues(stringArray);
// Set the CurrentCulture to "en-US".
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
// Sort the values of the array.
Array.Sort(stringArray);
// Display the values of the array.
Console.WriteLine("After sorting for the culture \"en-US\":");
PrintIndexAndValues(stringArray);
// Set the CurrentCulture to "da-DK".
Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
// Sort the values of the Array.
Array.Sort(stringArray);
// Display the values of the array.
Console.WriteLine("After sorting for the culture \"da-DK\":");
PrintIndexAndValues(stringArray);
}
public static void PrintIndexAndValues(string[] myArray)
{
for (int i = myArray.GetLowerBound(0); i <=
myArray.GetUpperBound(0); i++ )
Console.WriteLine("[{0}]: {1}", i, myArray[i]);
Console.WriteLine();
}
}
// The example displays the following output:
// The original string array:
// [0]: Apple
// [1]: Æble
// [2]: Zebra
//
// After sorting for the "en-US" culture:
// [0]: Æble
// [1]: Apple
// [2]: Zebra
//
// After sorting for the culture "da-DK":
// [0]: Apple
// [1]: Zebra
// [2]: Æble
Использование ключей сортировки
Ключи сортировки используются для поддержки сортировок, зависящих от культурной среды. На основе стандарта Юникод каждому символу в строке присваивается несколько весовых категорий сортировки, включая алфавитную, регистровую и диакритическую. Ключ сортировки служит хранилищем этих весовых коэффициентов для конкретной строки. Например, ключ сортировки может содержать строку с алфавитными весами, после которой идет строка с регистровыми весами и т. д. Дополнительные сведения о ключах сортировки см. на домашней странице стандарта Юникод.
В .NET Framework класс SortKey выполняет сопоставление строк с их ключами сортировки и наоборот. Чтобы создать требуемый ключ сортировки для указанной строки, в приложении можно использовать метод CompareInfo.GetSortKey. Результирующий ключ сортировки для определенной строки — это последовательность байтов, которая может различаться в зависимости от заданных значений CurrentCulture и CompareOptions. Например, если при создании ключа сортировки задать значение IgnoreCase, при выполнении операций сравнения строк с использованием ключа сортировки будет игнорироваться регистр символов.
После создания ключа сортировки для строки его можно передать в качестве параметра в методы, представленные классом SortKey. Метод SortKey.Compare поддерживает сравнение ключей сортировки. Поскольку метод осуществляет побайтовое сравнение, при его работе обеспечивается более высокая скорость по сравнению с методом String.Compare. Если в приложении активно используется сортировка, можно увеличить производительность путем создания и хранения ключей сортировки для всех используемых в нем строк. При выполнении операций сортировки или сравнения в приложении будут использоваться ключи сортировки вместо строк.
В следующем примере создаются ключи сортировки для двух строк (для параметра CurrentCulture задано значение "da-DK"). Выполняется сравнение двух строк с помощью метода SortKey.Compare с последующим выводом результата на экран. Метод возвращает отрицательное целое число (если строка string1 меньше, чем строка string2), ноль (0) (если string1 и string2 равны) или положительное целое число (если string1 больше, чем string2). Далее для параметра Thread.CurrentThread.CurrentCulture устанавливается значение "en-US" и создаются ключи сортировки для тех же строк. Выполняется сравнение ключей сортировки для строк с последующим выводом результата на экран. Результаты сортировки различаются в зависимости от значения параметра CurrentCulture. Несмотря на то, что результаты приведенного ниже примера идентичны результатам сравнения этих строк в примере Сравнение строк, приведенном ранее в этом разделе, метод SortKey.Compare быстрее, чем метод String.Compare.
Imports System.Globalization
Imports System.Threading
Public Class SortKeySample
Public Shared Sub Main()
Dim str1 As [String] = "Apple"
Dim str2 As [String] = "Æble"
' Set the CurrentCulture to "da-DK".
Dim dk As New CultureInfo("da-DK")
Thread.CurrentThread.CurrentCulture = dk
' Create 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)
' Compare the two sort keys and display the results.
Dim result1 As Integer = SortKey.Compare(sc1, sc2)
Console.WriteLine("When the current culture is ""da-DK"",")
Console.WriteLine("the result of comparing {0} with {1} is: {2}",
str1, str2, result1)
Console.WriteLine()
' Set the CurrentCulture to "en-US".
Dim enus As New CultureInfo("en-US")
Thread.CurrentThread.CurrentCulture = enus
' Create 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)
' Compare the two sort keys and display the results.
Dim result2 As Integer = SortKey.Compare(sc3, sc4)
Console.WriteLine("When the CurrentCulture is ""en-US"",")
Console.WriteLine("the result of comparing {0} with {1} is: {2}",
str1, str2, result2)
End Sub
End Class
' The example displays the following output:
' When the current culture 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
using System;
using System.Threading;
using System.Globalization;
public class SortKeySample
{
public static void Main(String[] args)
{
String str1 = "Apple";
String str2 = "Æble";
// Set the CurrentCulture to "da-DK".
CultureInfo dk = new CultureInfo("da-DK");
Thread.CurrentThread.CurrentCulture = dk;
// Create 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);
// Compare the two sort keys and display the results.
int result1 = SortKey.Compare(sc1, sc2);
Console.WriteLine("When the CurrentCulture is \"da-DK\",");
Console.WriteLine("the result of comparing {0} with {1} is: {2}\n",
str1, str2, result1);
// Set the CurrentCulture to "en-US".
CultureInfo enus = new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = enus ;
// Create 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);
// Compare the two sort keys and display the results.
int result2 = SortKey.Compare(sc3, sc4);
Console.WriteLine("When the CurrentCulture is \"en-US\",");
Console.WriteLine("the result of comparing {0} with {1} is: {2}",
str1, str2, result2);
}
}
// The example displays the following output:
// 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 определенные формы нормализации не являются обязательными или гарантированными. Ответственность за выполнение необходимой нормализации в приложении несет его разработчик.
Дополнительные сведения о нормализации строк см. в разделе Нормализация и сортировка.
См. также
Основные понятия
Строковые операции, не зависящие от языка и региональных параметров