[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Как правильно сделать поддержку юникода в программе



Alexey Pechnikov wrote:
> Попробую конкретизировать. Итак, юникод - UTF-8. Хотелось бы еще UTF16,
> хотя я ни разу его не использовал и не видел, чтобы кто-то использовал. Но
> движок sqlite имеет нативную поддержку UTF16, может пригодиться.

Ну значит UTF16 и следует использовать. Иначе ведь наверняка он будет
рассчитывать на 8-битовые строки, а значит поиск в UTF-8 будет работать не
так, как надо.

> Требуется ввод/вывод  - смотрел примеры перекодирования через iconv, вроде
> устраивает. Далее, нужно сравнение символов, сортировка строк, смена
> регистра.
> 
> Вот что требуется от функций смены регистра:
> 
> **     upper('ABC') -> 'abc'
> **     lower('abc') -> 'ABC'
> 
> **     lower('I', 'en_us') -> 'i'
> **     lower('I', 'tr_tr') -> 'ı' (small dotless i)
> 
> Сравнение с шаблоном, как я понимаю, через вышеперечисленное пишется, но
> хотелось бы пример, чтобы грамотно реализовать функции LIKE и REGEXP - они
> и так медленные, писать надо аккуратно.

LIKE и особенно REGEXP зависят от кодировки символов. Если есть уже в sqlite
поддержка UTF16, то и встроенные функции будут с ним работать как надо
(если sqlite будет знать, что это не 8 бит). Если использовать самому
библиотеку работы с регэкспами, то она должна быть рассчитана на уникод,
иначе ничего не получится.

В Linux представление wchar_t совпадает с уникодом (man unicode), поэтому
можно использовать towlower и т.п. В Windows вроде тоже (но только 16 бит),
на других платформах всё хуже. См. недавнее обсуждение в
fido7.ru.unix.prog. Вопрос, кстати, именно для той конференции.

Иначе довольно симпатичной выглядит небольшая библиотека libunicode.

> Названия символов в движке СУБД знать не требуется. А что такое
> "комбинированные символы"?

Уже ответили. Некоторые символы могут быть записаны комбинацией двух кодов
уникода — кода буквы и кода диакритического знака (ô = o + «шапочка»). Для
некоторых из них есть и собственный код, поэтому они могут быть записаны
двумя способами. Нужно канонизировать перед сравнением строк.

А ещё бывают «невидимые» символы. Например «мягкий перенос» (U+00AD). При
выводе не отображается, но может использоваться для указания возможности
переноса слова. При сравнении строк очевидно должен быть пропущен. Ещё
бывают символы, указывающие направление письма, и т. п. Всё это можно
игнорировать и решать проблемы по мере возникновения (но помнить, что они
будут).

> P.S. Есть кроссплатформенный способ реализации - забиндить нужные функции
> из тикля (питона, etc.).

Зависит от приложения. Если уже есть зависимость от какого-то большого
графического тулкита или скриптового языка, то в них уже есть работа с
уникодом.


Reply to: