[Из песочницы] PHP-инструменты для японского языка

Проработав год в Японской компании системным инженером, я выделил несколько моментов, которые обязательно должен знать программист, работающий с японским текстом.

В Японском языке 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
    );
}

Система ввода японского текста тоже особенная, она позволяет прямо с клавиатуры без дополнительных инструментов добавлять разные украшения: ♪♫☆★「」︎icon128x128.png♡. Всеми этими штуками буквально переполнены блоги, форумы, твиттеры и тому подобные места.

Проблема же заключается в том, что при попытке вставить некоторые эмодзи в обычную таблицу 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.: Первая публикация не удалась, комментарий модератора:

Ощущение, что статья обрывается где-то посередине. Дополните материал и опубликуйте еще раз.

То, что называется «дежавю» — с хабром произошел как раз случай, описанный в последнем примере, а именно: я добавил для наглядности символы в четырехбайтовой кодировке, что вызвало ошибку, и текст был сохранен в базу данных в обрезанном виде.

Комментарии (0)

© Habrahabr.ru