StringInfo и TextElementEnumerator в C# не могут правильно распознавать графемы

В C# StringInfo а также TextElementEnumerator классы предоставляют методы и свойства для текстовых элементов. И здесь мы можем найти определение текстового элемента.

.NET Framework определяет текстовый элемент как единицу текста, которая отображается в виде одного символа, то есть графемы. Текстовый элемент может быть любым из следующих:

Да, он говорит, что текстовый элемент - это графема в.NET. Я также тестировал некоторые символы Юникода, и это действительно казалось правдой, пока я не протестировал одну корейскую букву "".

Как мы все знаем, некоторые символы Юникода состоят из нескольких кодовых точек. Также мы можем столкнуться с последовательностями кодовых точек, и именно поэтому я использую StringInfo а также TextElementEnumerator вместо простого String,

StringInfo а также TextElementEnumerator мог бы сказать, если Chars были суррогатными парами правильно. И "\u0061\u0308", символ Unicode, который состоит из нескольких кодовых точек, был распознан как один текстовый элемент, как и ожидалось. Но что касается "\u1100\u1161", он не смог сказать, что это был также один элемент текста.

"\ u1100" - это начальная буква "ㄱ", а "\u1161" - это гласная буква "ㅏ". Они могут быть отдельными персонажами и показываться пользователям так же, как я пишу здесь, и вы можете увидеть их сейчас. Но если они используются вместе, они отображаются как один символ "가" вместо "ㄱㅏ".

Существует два способа представления корейского символа "가":

  1. Использование единой кодовой точки U+AC00 от Hangul Syllable.
  2. Используя две кодовые точки U+1100 и U+1161 от Jamo.

Большую часть времени используется первый. Последний редко используется, если честно, я не могу себе представить, когда он вообще используется... В любом случае, первая - это просто одна предварительно составленная буква, а вторая - это последовательность Lead и Vowel, которая рассматривается как один символ. При визуализации они выглядят точно так же, и оба на самом деле канонически эквивалентны. Также следующая строка возвращает true в C#:

"\u1100\u1161".Normalize() == "\uAC00"

интересно, почему Normalize() здесь прекрасно работает, когда C# не думает, что они являются одним целым текстовым элементом... Я думал, что это как-то связано с моей версией.NET, но оказывается, что это не так. Это происходит даже в Моно.

Я проверил это с ICU а также, и он мог бы правильно трактовать "\ u1100 \ u1161" как одну графему! Я изначально думал StringInfo а также TextElementEnumerator может устранить необходимость в ICU4C в некоторых простых случаях, поэтому я очень разочарован..

Вот мой вопрос:

Я что-то здесь не так делаю?

или же

Текстовый элемент в.NET не воспринимается пользователем в отличие от ICU?

1 ответ

Решение

Основная проблема заключается в том, что в соответствии с корейским стандартом KS X 1026, два джемо а также отличаются от их комбинированной формы , Фактически этот точный пример используется в официальном стандарте (см. Раздел 6.2).

Короче говоря, Microsoft пыталась следовать стандарту, но другие операционные системы и приложения не обязательно делают это. Следовательно, вы можете получить "искаженное" содержимое из другого программного обеспечения / платформ, которое, по-видимому, неправильно анализируется в Windows / в.NET, даже если оно анализируется "правильно" на этих платформах.

Вам нужно либо убедиться, что ваши данные в первую очередь правильно сформированы (маловероятно, учитывая, что де-факто стандарт должен полностью игнорировать официальный стандарт), либо вам придется использовать ICU (или аналогичную библиотеку) для решения этих проблем. случаев.

Другие вопросы по тегам