Guest

bidirectional translit

By: a guest on Dec 15th, 2011  |  syntax: PHP  |  size: 4.71 KB  |  hits: 22  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. <?php
  2.  
  3. /**
  4.  * Функция обратимой транслитерации на основе ГОСТ 16876-71
  5.  * @author http://space1000.ru
  6.  * @donate 16iGBgs1JW24QSrLZh47MtbxLSMtt5Mnyx
  7.  */
  8.  
  9. function translit_url($text,$decode = false)
  10. {
  11.   preg_match_all('/./u', $text, $text);
  12.   $text = $text[0];
  13.  
  14.   $simplePairs = array(
  15.     'а' => 'a'   ,   'л' => 'l'   ,   'у' => 'u'   ,  
  16.     'б' => 'b'   ,   'м' => 'm'   ,   'т' => 't'   ,
  17.     'в' => 'v'   ,   'н' => 'n'   ,   'ы' => 'y'   ,
  18.     'г' => 'g'   ,   'о' => 'o'   ,   'ф' => 'f'   ,
  19.     'д' => 'd'   ,   'п' => 'p'   ,  
  20.     'и' => 'i'   ,   'р' => 'r'   ,  
  21.    
  22.     'А' => 'A'   ,   'Л' => 'L'   ,   'У' => 'U'   ,
  23.     'Б' => 'B'   ,   'М' => 'M'   ,   'Т' => 'T'   ,
  24.     'В' => 'V'   ,   'Н' => 'N'   ,   'Ы' => 'Y'   ,
  25.     'Г' => 'G'   ,   'О' => 'O'   ,   'Ф' => 'F'   ,
  26.     'Д' => 'D'   ,   'П' => 'P'   ,  
  27.     'И' => 'I'   ,   'Р' => 'R'   ,  
  28.   );
  29.   $complexPairs = array(
  30.     'з' => 'z'   ,   'ц' => 'c'   ,   'к' => 'k'   ,
  31.     'ж' => 'zh'  ,   'ч' => 'ch'  ,   'х' => 'kh'  ,
  32.    
  33.     'е' => 'e'   ,   'с' => 's'   ,   'ё' => 'jo'  ,  
  34.     'э' => 'eh'  ,   'ш' => 'sh'  ,   'й' => 'jj'  ,  
  35.                      'щ' => 'shh' ,   'ю' => 'ju'  ,  
  36.                                       'я' => 'ja'  ,
  37.  
  38.     'З' => 'Z'   ,   'Ц' => 'C'   ,   'К' => 'K'   ,
  39.     'Ж' => 'ZH'  ,   'Ч' => 'CH'  ,   'Х' => 'KH'  ,
  40.    
  41.     'Е' => 'E'   ,   'С' => 'S'   ,   'Ё' => 'JO'  ,  
  42.     'Э' => 'EH'  ,   'Ш' => 'SH'  ,   'Й' => 'JJ'  ,  
  43.                      'Щ' => 'SHH' ,   'Ю' => 'JU'  ,  
  44.                                       'Я' => 'JA'  ,
  45.     'Ь' => "^'"  ,
  46.     'Ъ' => "^`"  ,
  47.     'ъ' => "`"   ,
  48.     'ь' => "'"   ,
  49.   );
  50.   $specialSymbols = array(
  51.     "_" => "__",
  52.     "-" => "_-",
  53.     "'" => "_'",
  54.     "`" => "_`",
  55.     "^" => "_^",
  56.     " " => "-",
  57.   );
  58.   $translitLatSymbols = array(
  59.     'a','l','u','b','m','t','v','n','y','g','o',
  60.     'f','d','p','i','r','z','c','k','e','s',
  61.     'A','L','U','B','M','T','V','N','Y','G','O',
  62.     'F','D','P','I','R','Z','C','K','E','S',
  63.   );
  64.   $simplePairsFlip = array_flip($simplePairs);
  65.   $complexPairsFlip = array_flip($complexPairs);
  66.   $specialSymbolsFlip = array_flip($specialSymbols);
  67.   $charsToTranslit = array_merge(
  68.     array_keys($simplePairs),
  69.     array_keys($complexPairs)
  70.   );
  71.   $translitTable = array();
  72.   foreach($simplePairs as $key => $val) $translitTable[$key] = $simplePairs[$key];
  73.   foreach($complexPairs as $key => $val) $translitTable[$key] = $complexPairs[$key];
  74.   foreach($specialSymbols as $key => $val) $translitTable[$key] = $specialSymbols[$key];
  75.   $result = "";
  76.  
  77.  
  78.   if($decode)
  79.   {
  80.     $char = array();
  81.     $nonTranslitArea = false;
  82.     for($pos = 0; $pos < count($text); $pos++)
  83.     {
  84.       $char[0] = $text[$pos];
  85.       $char[1] = isset($text[$pos+1]) ? $text[$pos+1] : null;
  86.       $char[2] = isset($text[$pos+2]) ? $text[$pos+2] : null;
  87.       // decode specsymbols!
  88.       foreach($specialSymbolsFlip as $key => $val)
  89.       {
  90.         $search = "";
  91.         for($j = 0; $j < strlen($key) ; $j++) $search.= $char[$j];
  92.         if($search == $key)
  93.         {
  94.           $result.= $val;
  95.           $pos += strlen($key) - 1;
  96.           continue 2;
  97.         }
  98.       }
  99.       // lone '_' symbol
  100.       if($char[0] == '_')
  101.       {
  102.         $nonTranslitArea = !$nonTranslitArea;
  103.         continue;
  104.       }
  105.       if($nonTranslitArea)
  106.       {
  107.         $result.= $char[0];
  108.       }
  109.       else
  110.       {
  111.         if(in_array($char[0],$simplePairs))
  112.         {
  113.           $result.= $simplePairsFlip[$char[0]];
  114.           continue;
  115.         }
  116.         foreach($complexPairsFlip as $key => $val)
  117.         {
  118.           $search = "";
  119.           for($j = 0; $j < strlen($key); $j++) $search.= $char[$j];
  120.           if($search == $key)
  121.           {
  122.             $result.= $val;
  123.             $pos += strlen($key) - 1;
  124.             continue 2;
  125.           }
  126.         }
  127.         // if nothing up worked
  128.         $result.= $char[0];
  129.         continue;
  130.       }
  131.     }
  132.   }
  133.   else
  134.   {
  135.     $nonTranslitArea = false;
  136.     foreach($text as $char)
  137.     {
  138.       if(in_array($char,array_keys($specialSymbols)))
  139.       {
  140.         $result.= $translitTable[$char];
  141.       }
  142.       elseif(in_array($char,$charsToTranslit))
  143.       {
  144.         if($nonTranslitArea)
  145.         {
  146.           $result.= "_";
  147.           $nonTranslitArea = false;
  148.         }
  149.         $result.= $translitTable[$char];
  150.       }
  151.       else
  152.       {
  153.         if(!$nonTranslitArea
  154.         && in_array($char,$translitLatSymbols))
  155.         {
  156.           $result.= "_";
  157.           $nonTranslitArea = true;
  158.         }
  159.         $result.= $char;
  160.       }
  161.     }
  162.   }
  163.   return $result;
  164. }