我想做的是从字符串中删除所有重音和变音符号,将"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"等效物替换它们。
iconv("utf-8","ascii//TRANSLIT",$input);
扩展示例
一个不需要设置语言环境或拥有巨大转换表的小技巧:
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(您应该已经这样做了)。
你也可以试试这个
$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
好的,我自己找到了一个明显的解决方案,但这不是最好的性能......
echo strtr(utf8_decode($input),
utf8_decode('ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ'),
'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy');
如果您使用的是WordPress,则可以使用内置函数remove_accents( $string )
https://codex.wordpress.org/Function_Reference/remove_accents
但是我注意到一个错误:它不适用于具有单个字符的字符串。
对于阿拉伯语和波斯语用户,我推荐这种方法来删除变音符号:
$diacritics = array('َ','ِ','ً','ٌ','ٍ','ّ','ْ','ـ');
$search_txt = str_replace($diacritics, '', $diacritics);
要在阿拉伯语键盘中键入变音符号,您可以在Windows编辑器中使用此Asci(这些代码是Asci而不是Unicode)代码直接键入音调符号或按住 Alt +(键入音调符号字符的代码)这是代码
ـَ(0243) ـِ(0246) ـُ(0245) ـً(0240)ـٍ(0242) ـٌ(0241) ـْ(0250) ـّ(0248) ــ(0220)
我发现这个在法语和德语中给出了最一致的结果。将元标记设置为 utf-8
,我将其放置在一个函数中以从单词数组中返回一行,并且效果很好。
htmlentities ( $line, ENT_SUBSTITUTE , 'utf-8' )
执行此操作的规范方法:
- 获取文本的规范化形式规范分解。有关 Unicode 规范化形式,请参见 https://unicode.org/reports/tr15/。
- 删除非间距标记。
- 获取其余文本的规范化形式规范组合。
https://unicode-org.github.io/icu/userguide/transforms/general/
例如,若要删除字符中的重音符号,请使用以下转换:
NFD; [:Nonspacing Mark:] Remove; NFC.
我有点不确定为什么当页面还注意到时,他们会给出这个例子
每个转换规则由两个冒号组成,后跟一个转换名称。
因此,我们将添加这些。您需要包装ICU
库的intl
扩展。
$t = 'Transliterator::createFromRules(':: NFD; ::[:Nonspacing Mark:] Remove; :: NFC;');
例
print $t->transliterate('أ');
这会将 U+0623(阿拉伯字母 Alef 上面有 Hamza)转换为 U+0627(阿拉伯字母 Alef),即它也适用于非拉丁字母及其重音。
您可以将[:Nonspacing Mark:]
替换为 [:Mn:]
。