PHP:将UTF-8字符串中的变音替换为最接近的7位ASCII等效项

jv2fixgn  于 12个月前  发布在  PHP
关注(0)|答案(8)|浏览(72)

我想做的是删除字符串中的所有重音和元音变音,将“lärm”转换为“larm”或“andré”转换为“andre”。我试图做的是utf8_decode字符串,然后使用strtr,但由于我的源文件保存为UTF-8文件,我不能输入ISO-8859-15字符的所有变音-编辑器插入UTF-8字符。
显然,解决这个问题的一个解决方案是有一个包含ISO-8859-15文件,但必须有一个更好的方法,而不是有另一个必要的包含?

echo strtr(utf8_decode($input), 
           'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ',
           'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy');

**更新:**也许我对我想做的事情有点不准确:我实际上并不想删除变音符号,而是用最接近的“一个字符ASCII”替换它们。

7nbnzgx9

7nbnzgx91#

iconv("utf-8","ascii//TRANSLIT",$input);

扩展示例

kqhtkvqz

kqhtkvqz2#

一个小技巧,不需要设置语言环境或有巨大的翻译表:

function Unaccent($string)
{
    if (strpos($string = htmlentities($string, ENT_QUOTES, 'UTF-8'), '&') !== false)
    {
        $string = html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1', $string), ENT_QUOTES, 'UTF-8');
    }

    return $string;
}

它正常工作的唯一要求是将文件保存为UTF-8(你已经应该这样做了)。

798qvoo8

798qvoo83#

你也可以试试这个

$string = "Fóø Bår";
$transliterator = Transliterator::createFromRules(':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: Lower(); :: NFC;', Transliterator::FORWARD);
echo $normalized = $transliterator->transliterate($string);

但您需要有http://php.net/manual/en/book.intl.php可用

mzaanser

mzaanser4#

好吧,我自己找到了一个明显的解决方案,但它不是最好的性能...

echo strtr(utf8_decode($input), 
           utf8_decode('ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ'),
           'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy');
anauzrmj

anauzrmj5#

如果你使用的是WordPress,你可以使用内置函数remove_accents( $string )
https://codex.wordpress.org/Function_Reference/remove_accents
但是我发现了一个bug:它不能处理只有一个字符的字符串。

knpiaxh1

knpiaxh16#

对于阿拉伯语和波斯语用户,我推荐这种方法来删除变音符号:

$diacritics = array('َ','ِ','ً','ٌ','ٍ','ّ','ْ','ـ');
    $search_txt = str_replace($diacritics, '', $diacritics);

对于在阿拉伯语键盘中键入变音符号u可以使用此Asci(这些代码是Asci不是Unicode)代码在Windows编辑器中直接键入变音符号或按住Alt +(键入变音字符的代码)这是代码
ـَ(0243) ـِ(0246) ـُ(0245) ـً(0240) ـٍ(0242) ـٌ(0241) ـْ(0250) ـّ(0248) ـ ـ(0220)

yrdbyhpb

yrdbyhpb7#

我发现这一个在法语和德语中给出了最一致的结果。将 meta标记设置为utf-8,我把它放在一个函数中,从单词数组中返回一行,效果很好。

htmlentities (  $line, ENT_SUBSTITUTE   , 'utf-8' )
h6my8fg2

h6my8fg28#

要做到这一点的标准方法:
1.获得文本的规范化形式典型分解。请参阅https://unicode.org/reports/tr15/了解Unicode规范化形式。
1.删除非间隔标记。
1.获取剩余文本的规范化形式规范组合。
https://unicode-org.github.io/icu/userguide/transforms/general/
例如,要删除字符的重音符号,请使用以下转换:
NFD; [:Nonspacing Mark:] Remove; NFC.
我有点不确定,为什么他们已经给了这个例子,因为这样的时候,网页还注意到
每个转换规则由两个冒号和一个转换名称组成。
我们将添加这些。您需要intl扩展来 Package ICU库。

$t = \Transliterator::createFromRules(':: NFD; ::[:Nonspacing Mark:] Remove; :: NFC;');

示例

print $t->transliterate('أ');

这将U+0623(阿拉伯字母Alef,上面有哈姆扎)转换为U+0627(阿拉伯字母Alef),即它也适用于非拉丁字母及其口音。
您可以将[:Nonspacing Mark:]替换为[:Mn:]

相关问题