[Из песочницы] PHP-инструменты для японского языка
Проработав год в Японской компании системным инженером, я выделил несколько моментов, которые обязательно должен знать программист, работающий с японским текстом.
Есть такая особенность у японцев: текст может быть записан двумя способами — так называемая «полная длина» (Zen-Kaku) и «половина длины» (Han-Kaku). Японский текст — это Zen-Kaku, европейский текст — это Han-Kaku, но в принципе любой европейский текст может быть записан как Zen-Kaku. Пример: SALE. Но особенно японцы любят зен-каку цифры: 123.
Зачем же японцам 3 алфавита? В первом кандзи (漢字) — записываются иероглифы. Второй — это хирагана (ひらがな), это, можно сказать, главный алфавит, потому что любой кандзи может быть записан хираганой. И третий — это катакана (カタカナ) и она — это то же самое, что и хирагана, за исключением того, что ею записываются иностранные слова.
Та же самая проблема и с регулярными выражениями. Есть дата в формате: 2016.20.20. Чтобы она распознавалась, обязательное условие модификатор «u» — Unicode.
Как и все, японцы не заморачиваются с адресами страниц и пишут прям в адрес японскими иероглифами, например, так:
Адрес верный, но чтобы его понимал, например, Curl, он должен быть закодирован:
Система ввода японского текста тоже особенная, она позволяет прямо с клавиатуры без дополнительных инструментов добавлять разные украшения: ♪♫☆★「」︎♡. Всеми этими штуками буквально переполнены блоги, форумы, твиттеры и тому подобные места.
А дело тут в том что utf8_general_ci — это конечно очень богатый набор символов, но он ограничен 3 байтами на символ и не содержит 4-байтовые эмодзи. Кодировка которая подойдет — это utf8mb4.
Надеюсь, данный материал будет полезен тем, кто работает с японским текстом, а также всем остальным для общего развития.
То, что называется «дежавю» — с хабром произошел как раз случай, описанный в последнем примере, а именно: я добавил для наглядности символы в четырехбайтовой кодировке, что вызвало ошибку, и текст был сохранен в базу данных в обрезанном виде.
В Японском языке 3 алфавита, что делает работу с текстом не такой простой, как в европейских языках. Начнем с самого простого и перейдем к более сложному.
Как и в России, в Японии остались сайты с однобайтовой кодировкой, переводим текст в UTF-8:
$output = iconv('Shift-JIS', 'UTF-8//IGNORE', $input);
Есть такая особенность у японцев: текст может быть записан двумя способами — так называемая «полная длина» (Zen-Kaku) и «половина длины» (Han-Kaku). Японский текст — это Zen-Kaku, европейский текст — это Han-Kaku, но в принципе любой европейский текст может быть записан как Zen-Kaku. Пример: SALE. Но особенно японцы любят зен-каку цифры: 123.
Чтобы перевести SALE в SALE:
public function toHanKaku($text)
{
return mb_convert_kana($text, 'a');
}
Зачем же японцам 3 алфавита? В первом кандзи (漢字) — записываются иероглифы. Второй — это хирагана (ひらがな), это, можно сказать, главный алфавит, потому что любой кандзи может быть записан хираганой. И третий — это катакана (カタカナ) и она — это то же самое, что и хирагана, за исключением того, что ею записываются иностранные слова.
Для перевода хираганы в катакану (はずれ в ハズレ) (одно и то же слово в разных алфавитах) воспользуемся той же функцией, только с другим ключем:
public function toKatakana($text)
{
return mb_convert_kana($text, 'C');
}
Та же самая проблема и с регулярными выражениями. Есть дата в формате: 2016.20.20. Чтобы она распознавалась, обязательное условие модификатор «u» — Unicode.
preg_match('/[\d]{4}.[\d]{2}.[\d]{2}/u', $text, $match);
Как и все, японцы не заморачиваются с адресами страниц и пишут прям в адрес японскими иероглифами, например, так:
ヤフー
Адрес верный, но чтобы его понимал, например, Curl, он должен быть закодирован:
public function japaneseUrlEncode($text)
{
return preg_replace_callback(
'/[^\x21-\x7e]+/', function($matches) {
return urlencode($matches[0]);
}, $text
);
}
Система ввода японского текста тоже особенная, она позволяет прямо с клавиатуры без дополнительных инструментов добавлять разные украшения: ♪♫☆★「」︎♡. Всеми этими штуками буквально переполнены блоги, форумы, твиттеры и тому подобные места.
Проблема же заключается в том, что при попытке вставить некоторые эмодзи в обычную таблицу utf8_general_ci, мы получим обрезанный текст и ошибку:
Warning: #1366 Incorrect string value: '\xF0\x9F\x98\x8ASI...' for column 'content' at row 1
А дело тут в том что utf8_general_ci — это конечно очень богатый набор символов, но он ограничен 3 байтами на символ и не содержит 4-байтовые эмодзи. Кодировка которая подойдет — это utf8mb4.
Пример текстовой красоты по-японски:
みなさまこんにちは★SIENAなんばパークス店です♡
本日は入荷したてのnewピアスのご紹介です♫
Но не всем подойдет менять кодировку, есть другое решение — удаляем 4-байтовые эмодзи:
public function clear4byte($string)
{
return preg_replace('%(?:
\xF0[\x90-\xBF][\x80-\xBF]{2} |
[\xF1-\xF3][\x80-\xBF]{3} |
\xF4[\x80-\x8F][\x80-\xBF]{2}
)%xs', '', $string);
}
Надеюсь, данный материал будет полезен тем, кто работает с японским текстом, а также всем остальным для общего развития.
P.S.: Первая публикация не удалась, комментарий модератора:
Ощущение, что статья обрывается где-то посередине. Дополните материал и опубликуйте еще раз.
То, что называется «дежавю» — с хабром произошел как раз случай, описанный в последнем примере, а именно: я добавил для наглядности символы в четырехбайтовой кодировке, что вызвало ошибку, и текст был сохранен в базу данных в обрезанном виде.