Мне хотелось бы знать, как сравнить строку, содержащую символы с лигатурами, с канонической версией без лигатур (представьте себе приложение для изучения французского языка, которое позволяет пользователю вводить oeuf или œuf взаимозаменяемо). Мне кажется, это называется «складыванием», но я могу ошибаться.
Я пробовал нормализовать свои строки с помощью NFKD, который, как я думал, разложит символ на составные части, но только некоторые кодовые точки Unicode поддерживают декомпозицию. (Конечно, мой пример символа «œ» этого не делает, что привело к частым выдергиваниям за волосы.)
Например:
Код: Выделить всё
using System.Text;
using System.Globalization;
// This character does not support decomposition.
string str1 = "\u0153"; // œ (LATIN SMALL LIGATURE OE)
string str2 = "oe";
string str1norm = str1.Normalize(NormalizationForm.FormKD);
Console.WriteLine(str1norm.IsNormalized()); // True
Console.WriteLine(str1norm.Equals(str2)); // False
Console.WriteLine(str1norm.Length); // 1
// This character supports decomposition.
str1 = "\uFB06"; // st (LATIN SMALL LIGATURE ST)
str2 = "st";
str1norm = str1.Normalize(NormalizationForm.FormKD);
Console.WriteLine(str1norm.IsNormalized()); // True
Console.WriteLine(str1norm.Equals(str2)); // True
// (Non-normalized comparison.) True in most locales, but not all (see below)
Console.WriteLine(str1.Equals(str2, StringComparison.CurrentCultureIgnoreCase));
Console.WriteLine(str1norm.Length); // 2
- https://www.compart.com/en /unicode/U+0153
- https://www.compart.com/en/unicode/U+FB06
- Как мне это определить, не проверяя вручную все кодовые точки Юникода?
- Могу ли я выполнить сравнение строк с канонической версией строки без необходимости создания словаря все неразложимые символы и их развернутые формы? Я имею в виду, что мне нравится печатать, но не так уж сильно.
- (Бонусный раунд.) Почему некоторые многосимвольные кодовые точки можно разложить (например, в примере с лигатурой 'st'), а некоторые нет ? Есть ли что-то особенное в таких символах, как «œ»?
В качестве последней иллюстрации моего «что-на-земле-происходит-происходит» ?" с точки зрения мышления на данный момент, 'st' эквивалентно 'st' без нормализации в 862 локалях на моем ПК, при этом сравнение строк завершается неудачей только в 7, причем эти локали ошибочны:
- (афарский язык)
Код: Выделить всё
aa - (Афар – Джибути)
Код: Выделить всё
aa-DJ - (Афар – Эритрея)
Код: Выделить всё
aa-ER - (Афар – Эфиопия)
Код: Выделить всё
aa-ET - (настройки POSIX на английском языке, США)
Код: Выделить всё
en-US-POSIX - (язык Сахо)
Код: Выделить всё
ssy - (Сахо - Эритрея)
Код: Выделить всё
ssy-ER
< em>Наконец, наконец, односимвольный символ 'f' и его разложенная форма 'st' равны в культуре .NET Invariant, но только если регистр игнорируется:
Код: Выделить всё
//...continuing from prior code...
Console.WriteLine(str1.Equals(str2, StringComparison.InvariantCulture)); // False
Console.WriteLine(str1.Equals(str2, StringComparison.InvariantCultureIgnoreCase)); // True
(Я знаю: «Просто нормализуйте свою строку и забудьте, что вы когда-либо видели это, Дэйв». Но я все равно думаю, что интересно узнать, почему это происходит.)
Спасибо, что уделили время.
Подробнее здесь: https://stackoverflow.com/questions/785 ... omparisons
Мобильная версия