Альтернативная транслитерация

С.

Продвинутый новичок
Мне понадобилась транслитерации с русского на латынь, но так, чтобы можно было перевести ее назад в кириллицу. Я использовал метод HK (Harvard-Kyoto) – обратимая транслитерация с санскрита и обратно. Адаптировал ее для русского.

Где она может пригодиться?
  1. Там, хранение ID в мультибайтах проблематично
  2. Альтернатива URL-code (визуальная читабельность)
Может кому-нибудь тоже пригодится.

PHP:
function hk_translit($str, $to='HK')
/*
    Transliteration RU<->HK (Harvard-Kyoto method)
    $to argument:
        HK -- Translterate to Latin (uppercase down)
        SAFE --Translterate to Latin (uppercase preserved)
        RU -- Back to Russian;
*/
{
    $trn=array(
        'а'=>'a', 'б'=>'b', 'в'=>'v', 'г'=>'g', 'д'=>'d', 'е'=>'e', 'ё'=>'O', 'ж'=>'Z', 'з'=>'z',
        'и'=>'i', 'й'=>'y', 'к'=>'k', 'л'=>'l', 'м'=>'m', 'н'=>'n', 'о'=>'o',
        'п'=>'p', 'р'=>'r', 'с'=>'s', 'т'=>'t', 'у'=>'u', 'ф'=>'f', 'х'=>'h', 'ц'=>'c', 'ч'=>'C',
        'ш'=>'S', 'щ'=>'T', 'ъ'=>'``', 'ы'=>'I', 'ь'=>'`', 'э'=>'E', 'ю'=>'U', 'я'=>'A',
    );   
    if ($to=='SAFE')
    {
        $chars= preg_split('//u', $str, null, PREG_SPLIT_NO_EMPTY);
        $str= '';
        foreach ($chars as $char)
        {
            $charNew= $trn[$char];
            if (!$charNew)
            {
                $testlower= mb_strtolower($char);
                if ($testlower==$char) $charNew= $char; // non-letter
                else // upper letter
                {
                    $charNew= $trn[$testlower];
                    $charNew= '^'.$charNew;
                }
            }
            $str.= $charNew;
        }
    }
    elseif ($to=='RU')
    {
        $trn= array_flip($trn);
        $caps= explode('^', $str);
        if (count($caps)>1)
        {
            $str= '';
            foreach ($caps as $word)
            {
                $word= strtr($word, $trn);
                $str.= mb_strtoupper(mb_substr($word,0,1)) . mb_substr($word,1);
            }
        }
        else $str= strtr($str, $trn);
    }
    else
    {
        $str= mb_strtolower($str);
        $str= strtr($str, $trn);
    }
    return $str;   
}
 

fixxxer

К.О.
Партнер клуба
PHP:
$transliterated = iconv('utf-8', 'koi-7', $ruUtf8String);
$reverted = iconv('koi-7', 'utf-8', $transliterated);
:)
 

fixxxer

К.О.
Партнер клуба
Не по теме, но не могу молчать.

function hk_translit($str, $to='HK')
/*
$to argument:
HK -- Translterate to Latin (uppercase down)
SAFE --Translterate to Latin (uppercase preserved)
RU -- Back to Russian;
Люди, зачем вы так делаете? Не надо так, пожалуйста!

Вот только на днях разгребал код с API вида $crypt->endecode($value, $op) // $op = "en" to encode, "de" to decode.
Ну вот зачем, ЗАЧЕМ ТАК? Что мешает сделать 2 метода?
 

fixxxer

К.О.
Партнер клуба
С реверсом все будет отлично, если не смешивать латиницу и кириллицу.
В полноценной реализации koi-7 начало и конец кириллического блока отбивается escape-символом, но iconv так не умеет, да.

Ограничения iconv мне известны.
Лишь хотел напомнить, что аналогичную задачу уже решали 25 лет назад, и в ряде случаев это решение вполне применимо и ныне.

Читабельность, кстати, там вполне, на всяких ДВК все прекрасно понимали, что такое "инжалид дежице" и наоборот. :D
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
От билда iconv-а зависит, видать.

В штатном iconv-е в убунтах 14.04 и 16.04 есть, больше под рукой нет ничего.
 

С.

Продвинутый новичок
Суть метода ХК состоит в том, что не нужны диакритические знаки.

Код:
sut` metoda hk sostoit v tom, Cto ne nuZnI diakritiCeskie znaki.
^sut` metoda ^h^k sostoit v tom, Cto ne nuZnI diakritiCeskie znaki.

Хотя для русского пришлось добавить два неалфабетика.
 
Сверху