StringInfo и TextElementEnumerator в C # не могут правильно распознавать графемы - PullRequest
0 голосов
/ 20 сентября 2018

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

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

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

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

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

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

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

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

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

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

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

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

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

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

или

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

1 Ответ

0 голосов
/ 25 сентября 2018

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

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

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

...