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】:如果您想对每个字母进行精确的双重转换,您需要稍微改进一下方法。 我有用于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);
【讨论】:
【参考方案3】:这个最适合我。 代码来自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【参考方案4】:
遵守 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 );
【讨论】:
【参考方案5】:
$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;
【讨论】:
【参考方案6】:这是我的俄文音译表版本。它是非官方的,但基于技术标准 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;
【讨论】:
【参考方案7】:这是我用来清理波斯尼亚语、克罗地亚语、塞尔维亚拉丁语字符的函数
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;
【讨论】:
【参考方案8】:@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” "。【参考方案9】:最好的选择是使用 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
【参考方案10】:
由于以上所有内容都不完整,这是我的版本:
$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,因为我正在使用这种方式。
【讨论】:
【参考方案11】:对我来说最好的解决方案是使用
strtr("Информация",array('И'=>'I','н'=>'n','ф'=>'f', ...and so on... ))
【讨论】:
【参考方案12】:$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 个答案中,没有人能写出完整的字母表。【参考方案13】:我为所有欧洲语言编写了一个完整的 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【参考方案14】:您应该尝试iconv()
与//TRANSLIT
选项。
$trstr = iconv(<your encoding here>, "ISO-8859-1//TRANSLIT", $src_str)
【讨论】:
我敢打赌这是正确的答案,但 iconv() 似乎不支持西里尔字符的音译。 啊,我明白了,iconv()
没有那个音译方案。不过 ICU 可以,所以如果你的 PHP 是用 ICU 编译的,你可以使用transliterate
。 (您可能需要在基于 Debian 的机器上 aptitude install php5-intl
。)以上是关于PHP 中的西里尔字母音译的主要内容,如果未能解决你的问题,请参考以下文章