PHP 中的西里尔字母音译

Posted

技术标签:

【中文标题】PHP 中的西里尔字母音译【英文标题】:Cyrillic transliteration in PHP 【发布时间】:2011-11-19 15:46:18 【问题描述】:

如何将西里尔字符音译成拉丁字母?

E.g. Главная страница -> Glavnaja stranica

这个Transliteration php Extension 可以很好地做到这一点,但我无法在我的服务器上安装它。

最好有相同的实现,但在 PHP 中。

【问题讨论】:

【参考方案1】:

试试下面的代码

$textcyr="Тествам с кирилица";
        $textlat="I pone dotuk raboti!";
        $cyr = ['Љ', 'Њ', 'Џ', 'џ', 'ш', 'ђ', 'ч', 'ћ', 'ж', 'љ', 'њ', 'Ш', 'Ђ', 'Ч', 'Ћ', 'Ж','Ц','ц', 'а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п', 'р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я', 'А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П', 'Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я'
        ];
        $lat = ['Lj', 'Nj', 'Dž', 'dž', 'š', 'đ', 'č', 'ć', 'ž', 'lj', 'nj', 'Š', 'Đ', 'Č', 'Ć', 'Ž','C','c', 'a','b','v','g','d','e','io','zh','z','i','y','k','l','m','n','o','p', 'r','s','t','u','f','h','ts','ch','sh','sht','a','i','y','e','yu','ya', 'A','B','V','G','D','E','Io','Zh','Z','I','Y','K','L','M','N','O','P', 'R','S','T','U','F','H','Ts','Ch','Sh','Sht','A','I','Y','e','Yu','Ya'
        ];
        $textcyr = str_replace($cyr, $lat, $textcyr);
        $textlat = str_replace($lat, $cyr, $textlat);
        echo("$textcyr $textlat");

【讨论】:

$lat 中的 "е" 是西里尔字母,与 "e" 不同,即使它们在视觉上是相同的 顺便说一句,这个数组中没有'ё'、'ы'和'э'字母 效果很好,你有最新版本和注释的站点/github 吗? $cyr 数组中有一个错字:'e' 实际上是拉丁文 'e'。它们看起来一样,但这会在进一步的转换中产生问题。 @TuralAliyev 谢谢,但我在 4 年前评论过这篇文章。它已经被编辑过。【参考方案2】:

@Tural Teyyuboglu

您的代码存在问题:如果您尝试将例如“щеки”音译为拉丁语,然后再转回西里尔语,则会产生类似“схтеки”的内容。多字节字符必须首先出现在数组中,如下所示:

function transliterate($textcyr = null, $textlat = null) 
    $cyr = array(
    'ж',  'ч',  'щ',   'ш',  'ю',  'а', 'б', 'в', 'г', 'д', 'е', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ъ', 'ь', 'я',
    'Ж',  'Ч',  'Щ',   'Ш',  'Ю',  'А', 'Б', 'В', 'Г', 'Д', 'Е', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ъ', 'Ь', 'Я');
    $lat = array(
    'zh', 'ch', 'sht', 'sh', 'yu', 'a', 'b', 'v', 'g', 'd', 'e', 'z', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'y', 'x', 'q',
    'Zh', 'Ch', 'Sht', 'Sh', 'Yu', 'A', 'B', 'V', 'G', 'D', 'E', 'Z', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F', 'H', 'c', 'Y', 'X', 'Q');
    if($textcyr) return str_replace($cyr, $lat, $textcyr);
    else if($textlat) return str_replace($lat, $cyr, $textlat);
    else return null;

echo transliterate(null, transliterate("щеки")) == "щеки";

【讨论】:

我用字典中的 40k 个单词测试了我的代码,它在“безизходен”​​->“bezizoden”->“безижоден”​​等情况下存在缺陷。如果我设法找到一个既保持人类可读性又无损的解决方案,我将发布解决方案(在我的网站上)。 是的。我发现没有万无一失的解决方案。一个字母表有大约 30 个字符,另一个有大约 26 个字符。 $cyr 数组中有一个错字:'e' 实际上是拉丁文 'e'。它们看起来一样,但这会在进一步的转换中产生问题。 您缺少 Ы 和 Ё。 很有用,谢谢!但是,此转换表对字母“ц”、“ъ”、“ь”和“я”使用所谓的“聊天拼写”。如果要使其符合音译规则,则需要更改“ц”=>“ts”,“ъ”=>“a”,“ь”=>“y”和“я”=>“ya” "。【参考方案3】:

最好的选择是使用 PHP Intl Extension。 您可能首先需要install it。

这样就可以了:

$transliteratedString = transliterator_transliterate('Russian-Latin/BGN', $cyrillicString);

我申请了“Russian-Latin/BGN”,因为提问者在他的问题中使用了俄语。但是,还有其他用西里尔字母编写的语言的选项。要查看所有这些,请执行以下操作:

print_r(transliterator_list_ids());

【讨论】:

在centos 7和php 7.1下可以使用yum install php71w-intl【参考方案4】:

您应该尝试iconv()//TRANSLIT 选项。

$trstr = iconv(<your encoding here>, "ISO-8859-1//TRANSLIT", $src_str)

【讨论】:

我敢打赌这是正确的答案,但 iconv() 似乎不支持西里尔字符的音译。 啊,我明白了,iconv() 没有那个音译方案。不过 ICU 可以,所以如果你的 PHP 是用 ICU 编译的,你可以使用transliterate。 (您可能需要在基于 Debian 的机器上 aptitude install php5-intl 。)【参考方案5】:
$textcyr="Тест на кирилице";
$textlat="Test na kirilitse!";
$cyr  = array('а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с','т','у', 
            'ф','х','ц','ч','ш','щ','ъ', 'ы','ь', 'э', 'ю','я','А','Б','В','Г','Д','Е','Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У',
            'Ф','Х','Ц','Ч','Ш','Щ','Ъ', 'Ы','Ь', 'Э', 'Ю','Я' );
$lat = array( 'a','b','v','g','d','e','io','zh','z','i','y','k','l','m','n','o','p','r','s','t','u',
            'f' ,'h' ,'ts' ,'ch','sh' ,'sht' ,'a', 'i', 'y', 'e' ,'yu' ,'ya','A','B','V','G','D','E','Zh',
            'Z','I','Y','K','L','M','N','O','P','R','S','T','U',
            'F' ,'H' ,'Ts' ,'Ch','Sh' ,'Sht' ,'A' ,'Y' ,'Yu' ,'Ya' );

$textcyr = str_replace($cyr, $lat, $textcyr);
$textlat = str_replace($lat, $cyr, $textlat);
echo("$textcyr $textlat");

缺少ё、э、ы(Э、Ы、Ё)字母

【讨论】:

big Ё 仍然不见了。在 3 个答案中,没有人能写出完整的字母表。【参考方案6】:

这是我用来清理波斯尼亚语、克罗地亚语、塞尔维亚拉丁语字符的函数

 function cleanUTF($name)
        $name = str_replace(array('š','č','đ','č','ć','ž','ñ'),array('s','c','d','c','c','z','n'), $name);
        $name = str_replace(array('Š','Č','Đ','Č','Ć', 'Ž','Ñ'),array('S','C','D','C','C','Z','N'), $name);
        $name = str_replace(array('а','б','в','г','д','е','ё','ж','з','и','й','к','л','љ','м','н','њ','о','п','р','с','т','у','ф','х','ц','ч','џ','ш','щ','ъ','ы','ь','э','ю','я','А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','Љ','М','Н','Њ','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Џ','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я'),
                            array('a','b','v','g','d','e','e','z','z','i','j','k','l','lj','m','n','nj','o','p','r','s','t','u','f','h','c','c','dz','s','s','i','j','j','e','ju','ja','A','B','V','G','D','E','E','Z','Z','I','J','K','L','Lj','M','N','Nj','O','P','R','S','T','U','F','H','C','C','Dz','S','S','I','J','J','E','Ju','Ja'), $name);
        return $name;
    

【讨论】:

【参考方案7】:

这是我的俄文音译表版本。它是非官方的,但基于技术标准 GOST 7.79-2000 和 GOST 16876-71。多字符优先。

public static function transliterate($textcyr = null, $textlat = null) 
    $cyr = array(
        'ё',  'ж',  'х',  'ц',  'ч',  'щ',   'ш',  'ъ',  'э',  'ю',  'я',  'а', 'б', 'в', 'г', 'д', 'е', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'ь',
        'Ё',  'Ж',  'Х',  'Ц',  'Ч',  'Щ',   'Ш',  'Ъ',  'Э',  'Ю',  'Я',  'А', 'Б', 'В', 'Г', 'Д', 'Е', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Ь');
    $lat = array(
        'yo', 'zh', 'kh', 'ts', 'ch', 'shh', 'sh', '``', 'eh', 'yu', 'ya', 'a', 'b', 'v', 'g', 'd', 'e', 'z', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', '`',
        'Yo', 'Zh', 'Kh', 'Ts', 'Ch', 'Shh', 'Sh', '``', 'Eh', 'Yu', 'Ya', 'A', 'B', 'V', 'G', 'D', 'E', 'Z', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F', '`');
    if($textcyr)
        return str_replace($cyr, $lat, $textcyr);
    else if($textlat)
        return str_replace($lat, $cyr, $textlat);
    else
        return null;

【讨论】:

【参考方案8】:

我为所有欧洲语言编写了一个完整的 utf-8 音译类。可能会有所帮助(cmets 是波兰语,但数量不多,所以这里有一些提示:

    存储在常量中的数字是本地数据库中的 idCountry - 您可以随意更改它们。 “Rób transliterację dla”的意思是“为”进行音译 - 您通过 const 名称确定国家/地区。 “Słownik tłumaczący rosyjską cyrylicę wg standardu”的意思是“按标准音译的字典” “Tablica wycinająca akcenty z różnych znaków narodowych pobrana z http://stuffofinterest.com/misc/utf8-about.html”的意思是“用于切断来自不同语言的重音的数组”(如果您在 iconv 中发现一些错误(或由于某种原因无法使用它),它可能会有所帮助。 utf2ascii 和 cyr2lat 方法非常明显。

希望它能帮助一些人,因为实施它是一场噩梦 :)

编辑:我刚刚注意到部分代码丢失了,所以我将整个课程放在 Pastie 上:class

【讨论】:

我担心有人可以删除或编辑它,所以如果您有更好的安全分享位置,请告诉我。 看起来很有希望。我试试看,谢谢。 Github 是一个非常好的分享代码的地方。 在相当大的系统上测试过,在生产中工作,所以它可以工作...... :) 但至于 github,我想对其进行一些重构(分成更多类)并在 go 之前翻译 cmets真正的开源”:] 感谢分享,这是迄今为止我找到的最好的 sn-p。 @ptyskju 这里:github.com/moby04/Transliteration/blob/master/translit.php【参考方案9】:

遵守 Yandex 音译规则 (http://www.translityandex.ru/) 并转换大写:

function translit_russian_filenames( $filename ) 
    $info = pathinfo( $filename );
    $ext  = empty( $info['extension'] ) ? '' : '.' . $info['extension'];
    $name = basename( $filename, $ext );
     $cyr = array(
    'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я',
    'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'ы', 'Ь', 'Э', 'Ю', 'Я' );
    $lat = array(
    'a', 'b', 'v', 'g', 'd', 'e', 'yo', 'zh', 'z', 'i', 'y', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'ch', 'sh', 'shch', '', 'y', '', 'e', 'yu', 'ya',
    'a', 'b', 'v', 'g', 'd', 'e', 'yo', 'zh', 'z', 'i', 'y', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'ch', 'sh', 'shch', '', 'y', '', 'e', 'yu', 'ya');
    $name_translit = str_replace($cyr, $lat, $name);
    return $name_translit . $ext;

add_filter( 'sanitize_file_name', 'translit_russian_filenames', 10 );

【讨论】:

【参考方案10】:

这个最适合我。 代码来自this page

function ru2lat($str)

    $tr = array(
    "А"=>"a", "Б"=>"b", "В"=>"v", "Г"=>"g", "Д"=>"d",
    "Е"=>"e", "Ё"=>"yo", "Ж"=>"zh", "З"=>"z", "И"=>"i", 
    "Й"=>"j", "К"=>"k", "Л"=>"l", "М"=>"m", "Н"=>"n", 
    "О"=>"o", "П"=>"p", "Р"=>"r", "С"=>"s", "Т"=>"t", 
    "У"=>"u", "Ф"=>"f", "Х"=>"kh", "Ц"=>"ts", "Ч"=>"ch", 
    "Ш"=>"sh", "Щ"=>"sch", "Ъ"=>"", "Ы"=>"y", "Ь"=>"", 
    "Э"=>"e", "Ю"=>"yu", "Я"=>"ya", "а"=>"a", "б"=>"b", 
    "в"=>"v", "г"=>"g", "д"=>"d", "е"=>"e", "ё"=>"yo", 
    "ж"=>"zh", "з"=>"z", "и"=>"i", "й"=>"j", "к"=>"k", 
    "л"=>"l", "м"=>"m", "н"=>"n", "о"=>"o", "п"=>"p", 
    "р"=>"r", "с"=>"s", "т"=>"t", "у"=>"u", "ф"=>"f", 
    "х"=>"kh", "ц"=>"ts", "ч"=>"ch", "ш"=>"sh", "щ"=>"sch", 
    "ъ"=>"", "ы"=>"y", "ь"=>"", "э"=>"e", "ю"=>"yu", 
    "я"=>"ya", " "=>"-", "."=>"", ","=>"", "/"=>"-",  
    ":"=>"", ";"=>"","—"=>"", "–"=>"-"
    );
return strtr($str,$tr);

希望这对某人有所帮助。

【讨论】:

我偶然发现了这条评论,我无法理解它应该如何工作。 strstr 在我尝试执行时显示错误needle is not a string or an integer @Moseleyi 这个函数只是简单地替换子字符串,php.net/manual/en/function.strtr.php【参考方案11】:

如果您想对每个字母进行精确的双重转换,您需要稍微改进一下方法。 我有用于url的翻译,用数据库搜索url参数。这就是为什么保持准确的字符而不用另一个替换对我来说非常重要。

!!!支持乌克兰符号。

/**
 * @param $string
 *
 * @return string only cyrillic letter
 */
function to_cyrillic($string):string

    $gost = [
        "a" => "а", "b" => "б", "v" => "в", "g" => "г", "d" => "д", "e" => "е", "yo" => "ё",
        "j" => "ж", "z" => "з", "ii" => "и", "ji" => "й", "k" => "к",
        "l" => "л", "m" => "м", "n" => "н", "o" => "о", "p" => "п", "r" => "р", "s" => "с", "t" => "т",
        "y" => "у", "f" => "ф", "h" => "х", "c" => "ц",
        "ch" => "ч", "sh" => "ш", "sch" => "щ", "ie" => "ы", "u" => "у", "ya" => "я", "A" => "А", "B" => "Б",
        "V" => "В", "G" => "Г", "D" => "Д", "E" => "Е", "Yo" => "Ё", "J" => "Ж", "Z" => "З", "I" => "И", "Ji" => "Й",
        "K" => "К", "L" => "Л", "M" => "М",
        "N" => "Н", "O" => "О", "P" => "П",
        "R" => "Р", "S" => "С", "T" => "Т", "Y" => "Ю", "F" => "Ф", "H" => "Х", "C" => "Ц", "Ch" => "Ч", "Sh" => "Ш",
        "Sch" => "Щ", "Ie" => "Ы", "U" => "У", "Ya" => "Я", "'" => "ь", "_'" => "Ь", "''" => "ъ", "_''" => "Ъ",
        "yi" => "ї", "ge" => "ґ",
        "ye" => "є",
        "Yi" => "Ї",
        "II" => "І",
        "Ge" => "Ґ",
        "YE" => "Є",
    ];
    return strtr($string, $gost);


/**
 * @param $string
 *
 * @return string only latin letter
 */
function to_latin($string):string

    $gost = [
        "а" => "a", "б" => "b", "в" => "v", "г" => "g", "д" => "d",
        "е" => "e", "ё" => "yo", "ж" => "j", "з" => "z", "и" => "ii",
        "й" => "ji", "к" => "k", "л" => "l", "м" => "m", "н" => "n",
        "о" => "o", "п" => "p", "р" => "r", "с" => "s", "т" => "t",
        "у" => "y", "ф" => "f", "х" => "h", "ц" => "c", "ч" => "ch",
        "ш" => "sh", "щ" => "sch", "ы" => "ie", "э" => "e", "ю" => "u",
        "я" => "ya",
        "А" => "A", "Б" => "B", "В" => "V", "Г" => "G", "Д" => "D",
        "Е" => "E", "Ё" => "Yo", "Ж" => "J", "З" => "Z", "И" => "I",
        "Й" => "Ji", "К" => "K", "Л" => "L", "М" => "M", "Н" => "N",
        "О" => "O", "П" => "P", "Р" => "R", "С" => "S", "Т" => "T",
        "У" => "Y", "Ф" => "F", "Х" => "H", "Ц" => "C", "Ч" => "Ch",
        "Ш" => "Sh", "Щ" => "Sch", "Ы" => "Ie", "Э" => "E", "Ю" => "U",
        "Я" => "Ya",
        "ь" => "'", "Ь" => "_'", "ъ" => "''", "Ъ" => "_''",
        "ї" => "yi",
        "і" => "ii",
        "ґ" => "ge",
        "є" => "ye",
        "Ї" => "Yi",
        "І" => "II",
        "Ґ" => "Ge",
        "Є" => "YE",
    ];
    return strtr($string, $gost);

【讨论】:

【参考方案12】:

由于以上所有内容都不完整,这是我的版本:

    $textcyr="Тест на кирилице";
    $textlat="Test na kirilitse!";
         $cyr  = array('а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с','т','у', 
            'ф','х','ц','ч','ш','щ','ъ', 'ы','ь', 'э', 'ю','я',
            'А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У',
            'Ф','Х','Ц','Ч','Ш','Щ','Ъ', 'Ы','Ь', 'Э', 'Ю','Я' );
$lat = array( 'a','b','v','g','d','e','e','zh','z','i','y','k','l','m','n','o','p','r','s','t','u',
            'f' ,'h' ,'ts' ,'ch','sh' ,'sht' ,'i', 'y', 'y', 'e' ,'yu' ,'ya','A','B','V','G','D','E','E','Zh',
            'Z','I','Y','K','L','M','N','O','P','R','S','T','U',
            'F' ,'H' ,'Ts' ,'Ch','Sh' ,'Sht' ,'I' ,'Y' ,'Y', 'E', 'Yu' ,'Ya' );

    $textcyr = str_replace($cyr, $lat, $textcyr);
    $textlat = str_replace($lat, $cyr, $textlat);
    echo("$textcyr $textlat");

我更喜欢 ё = e、ъ = i、ы = y 和 э = e,因为我正在使用这种方式。

【讨论】:

【参考方案13】:

对我来说最好的解决方案是使用

strtr("Информация",array('И'=>'I','н'=>'n','ф'=>'f', ...and so on... ))

【讨论】:

【参考方案14】:

$textcyr = 'Њушка Ћушка Љубав Ђато ђата части ';

$textlat = 'Ljubav njuška džoša Džoša';
$textlat = str_replace("nj","њ",$textlat);
$textlat = str_replace("Nj","Њ",$textlat);
$textlat = str_replace("lj","љ",$textlat);
$textlat = str_replace("Lj","Љ",$textlat);
$textlat = str_replace("dž","џ",$textlat);
$textlat = str_replace("Dž","Џ",$textlat);


$textcyr = str_replace($cyr, $lat, $textcyr);
$textlat = str_replace($lat, $cyr, $textlat);

echo $textcyr;
echo $textlat;

【讨论】:

以上是关于PHP 中的西里尔字母音译的主要内容,如果未能解决你的问题,请参考以下文章

音译/转置NSString中的字符

Paradox DB:查询中的西里尔字母,C#

数学符号λ的用法

姜戈。非 ascii 字段不会创建 slug。我希望得到音译,但得到一个空字段和错误

支持 BigQuery 中的西里尔文数据

Unity 中的回调 OnStreamMessageHandler 仅返回西里尔字符串的一半