Как конвертировать объединенные символы UTF8 в отдельные символы UTF8 в рубине?
Некоторые символы, такие как символ Юникода "LATIN SMALL LETTER C WITH CARON", могут быть закодированы как 0xC4 0x8D
, но также могут быть представлены двумя кодовыми точками для "LATIN SMALL LETTER C" и "COMBINING CARON", которые 0x63 0xcc 0x8c
.
Подробнее здесь: http://www.fileformat.info/info/unicode/char/10d/index.htm
Интересно, есть ли библиотека, которая может конвертировать "LATIN SMALL LETTER C" + "КОМБИНИРОВАНИЕ КАРОНА" в "ЛАТИНСКОЕ МАЛОЕ ПИСЬМО C С КАРОНОМ". Или есть таблица, содержащая эти преобразования?
Ответы
Ответ 1
Как правило, вы используете Unicode Normalization для этого.
Использование UnicodeUtils.nfkc с использованием гема unicode_utils (https://github.com/lang/unicode_utils) должно дать вам конкретное поведение, о котором вы просите; Форма нормализации unicode kC будет использовать декомпозицию совместимости с последующим преобразованием строки в составленную форму, если она доступна (в основном то, что вы просили в своем примере). (Вы также можете приблизиться к тому, что вы хотите, с помощью формы нормализации c, иногда сокращенно NFC).
Как заменить гем Unicode на Ruby 1.9? имеет дополнительные детали.
В Ruby 1.8.7 вам понадобится установить Gem Unicode, для которого доступна аналогичная функция.
Отредактировано, чтобы добавить: Основная причина, почему вы, вероятно, захотите форму нормализации kC вместо простой формы нормализации C, состоит в том, что лигатуры (символы, которые сжимаются вместе по историческим/типографским причинам) сначала будут разлагаться на отдельные символы, что иногда желательно если вы делаете лексикографический заказ или поиск).
Ответ 2
Эти преобразования не всегда существуют. Комбинация U + 0063 (c) с U + 030C (комбинация карона) может быть представлена, например, как один символ, но нет предкомпозиционного символа, представляющего нижний регистр w с кароном (w̌).
Тем не менее, существуют библиотеки, которые могут выполнять эту композицию там, где это возможно. Найдите функцию Unicode под названием "NFC" (форма нормализации: композиция). См., Например: http://unicode-utils.rubyforge.org/classes/UnicodeUtils.html#M000015
Ответ 3
String # encode может использоваться с Ruby 1.9. UTF-8-MAC является вариантом NFD. Кодовые точки в диапазоне между U + 2000 и U + 2FFF, или U + F900 и U + FAFF, или U + 2F800 и U + 2FAFF не разлагаются. Подробнее см. https://developer.apple.com/library/mac/qa/qa1173/_index.html. UTF-8-HFS также может использоваться в UTF-8-MAC.
# coding: utf-8
s = "\u010D"
s.encode!('UTF-8-MAC', 'UTF-8')
s.force_encoding('UTF-8')
p "\x63\xcc\x8c" == s
p "\u0063" == s[0]
p "\u030C" == s[1]