PHP转换音译

19

有没有解决方案可以将所有外语字符转换为A-z的等价字符?我在Google上进行了广泛搜索,但没有找到解决方案或字符和等价物的列表。原因是我想显示仅包含A-z的URL以及处理这些字符时的其他问题。


正如所指出的,一个粗略的拉丁字母表转换列表就足够了。 - user137621
3
最近版本的 PHP(PHP 5.4)新增了一个“Transliteration Class”类。 - bakytn
1
Transliterator 类(intl 扩展 - hakre
10个回答

24

1
我在继续研究时偶然发现了iconv,非常感谢您给我提供完整示例的链接。谢谢。 - user137621
1
你应该将Shane O'Grady的答案纳入其中。 - Quamis
你不应该使用iconv来进行这项工作。不同的系统可能有不同的iconv库,因此结果不能保证(更准确地说-可以保证结果会不同),所以请注意! - Velda

13
如果您使用了iconv,请确保在尝试转换前正确设置了语言环境,否则一些字符将无法正确地进行转换。
setlocale(LC_CTYPE, 'en_US.UTF8');

9
这将尽可能地将外文字符(包括西里尔文、中文、阿拉伯文等)转换为它们对应的A-z字符:
$AzString = transliterator_transliterate('Any-Latin;Latin-ASCII;', $foreignString);

你可能需要先安装 PHP Intl 扩展,才能进行下一步操作。点击此处了解如何安装。

3
Debian(Ubuntu)的命令:sudo aptitude install php5-intl。在这里,您可以找到完整的功能以获取漂亮的文件名或URL - Jasom Dotnet

7
如果您被困在不支持PHP 5.4或更新版本的开发和发布环境中,您应该使用iconv或自定义转换库。
就iconv而言,我发现它在阿拉伯语或西里尔字母上使用时非常无用。我会选择PHP 5.4内置的Transliteration类或自定义Transliteration类。
其中一个解决方案提到了一个自定义库,但我没有测试过。
当我使用Drupal时,我喜欢他们的transliteration模块,最近我将其移植使其可以在没有Drupal的情况下使用。

您可以在这里下载它,并按如下方式使用:

<?php

include "JTransliteration.php";

$mombojombotext = "誓曰:『時日害喪?予及女偕亡。』民欲與之偕亡,雖有";
$nonmombojombotex = JTransliteration::transliterate($mombojombotext);

echo $nonmombojombotex;

?>

1
发现这非常有用,但是你有一条提示:注意:在/路径/JTransliteration.php的第207行尝试获取非对象属性。我已经根据自己的需求解决了这个问题;) - Zuul
1
我的解决方法是删除第206行,并将第207行替换为$langcode = "UTF-8"; - Zuul
这是另一个更为实时的版本: https://github.com/Behat/Transliterator,可通过composer安装。 - jaywilliams

4
注意:我将此内容从另一个类似的问题中转载过来,希望这对他人有所帮助。
我最终编写了一个基于Django项目中URLify.js的PHP库,因为我发现iconv()太不完整了。你可以在这里找到它:

https://github.com/jbroadway/urlify

支持拉丁字符以及希腊、土耳其、俄罗斯、乌克兰、捷克、波兰和拉脱维亚的字符。


1
尝试这个。
function Unaccent( $string ) {

$transliterator = Transliterator::createFromRules(':: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;', Transliterator::FORWARD);

$normalized = $transliterator->transliterate($string);

return $normalized;

}

1
<?php
/**
 * @author bulforce[]gmail.com # 2011
 * Simple class to attempt transliteration of bulgarian lating text into bulgarian cyrilic text
 */

// Usage:
// $text = "yagoda i yundola";
// $tl = new Transliterate();
// echo $tl->lat_to_cyr($text); //ягода и юндола

class Transliterate {

    private $cyr_identical = array("а", "б", "в", "в", "г", "д", "е", "ж", "з", "и", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ъ", "я");
    private $lat_identical = array("a", "b", "v", "w", "g", "d", "e", "j", "z", "i", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "h", "c", "y", "q");
    private $cyr_fricative = array("ж", "ч", "ш", "щ", "ц", "я", "ю", "я", "ю");    
    private $lat_fricative = array("zh", "ch", "sh", "sht", "ts", "ia", "iu", "ya", "yu");

    public function __construct() {
        $this->identical_to_upper();
        $this->fricative_to_variants();
    }

    public function lat_to_cyr($str) {

        for ($i = 0; $i < count($this->cyr_fricative); $i++) {
            $c_cyr = $this->cyr_fricative[$i];
            $c_lat = $this->lat_fricative[$i];
            $str = str_replace($c_lat, $c_cyr, $str);
        }

        for ($i = 0; $i < count($this->cyr_identical); $i++) {
            $c_cyr = $this->cyr_identical[$i];
            $c_lat = $this->lat_identical[$i];
            $str = str_replace($c_lat, $c_cyr, $str);
        }

        return $str;
    }

    private function identical_to_upper() {

        foreach ($this->cyr_identical as $k => $v) {
            $this->cyr_identical[] = mb_strtoupper($v, 'UTF-8');
        }

        foreach ($this->lat_identical as $k => $v) {
            $this->lat_identical[] = mb_strtoupper($v, 'UTF-8');
        }
    }

    private function fricative_to_variants() {
        foreach ($this->lat_fricative as $k => $v) {
            // This handles all chars to Upper
            $this->lat_fricative[] = mb_strtoupper($v, 'UTF-8');
            $this->cyr_fricative[] = mb_strtoupper($this->cyr_fricative[$k], 'UTF-8');

            // This handles variants
            // TODO: fix the 3 leter sounds
            for ($i = 0; $i <= count($v); $i++) {
                $v[$i] = mb_strtoupper($v[$i], 'UTF-8');
                $this->lat_fricative[] = $v;
                if ($i == 0) {
                    $this->cyr_fricative[] = mb_strtoupper($this->cyr_fricative[$k], 'UTF-8');
                } else {
                    $this->cyr_fricative[] = $this->cyr_fricative[$k];
                }
                $v[$i] = mb_strtolower($v[$i], 'UTF-8');
            }
        }
    }

}

1
对于熟练使用composer的人,有slugify。

https://github.com/cocur/slugify

use Cocur\Slugify\Slugify;
$slugify = new Slugify();
echo $slugify->slugify('Hello World!'); // hello-world

//You can also change the separator used by Slugify:
echo $slugify->slugify('Hello World!', '_'); // hello_world

//The library also contains Cocur\Slugify\SlugifyInterface. Use this interface whenever you need to type hint an instance of Slugify.
//To add additional transliteration rules you can use the addRule() method.
$slugify->addRule('i', 'ey');
echo $slugify->slugify('Hi'); // hey

0

0

你的查询问题在于它是一件非常困难的事情。大多数语言中并不是所有的字形都有a-z的等效物,所有的字形都有音标等效物(但这些是单词而不是字母),如果你只处理基于拉丁语系的语言,那么事情会变得稍微容易一些,但你仍然会遇到像I-mutation这样的问题。

你最好的解决方案是制定一个粗略的音标列表-> a-z等效物,它不会完美无缺,但如果没有更多关于你确切要求的信息,很难开发出一个解决方案。


我主要处理欧洲语言,粗略的解决方案也可以,我曾经在另一个脚本的源代码中找到了一个大列表,但现在已经完全丢失了。 - user137621

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接