在PHP中用"等效"的ASCII字符替换带变音符号的字符?

17
5个回答

35
iconv 模块可以做到这一点,更具体地说,是通过 iconv() 函数实现的。
$str = iconv('Windows-1252', 'ASCII//TRANSLIT//IGNORE', "Gracišce");
echo $str;
//outputs "Gracisce"

使用iconv的主要麻烦之处在于你必须注意编码,但它绝对是完成工作的正确工具(由于我使用的文本编辑器的限制,我在示例中使用了'Windows-1252'编码 ;) 你绝对想要使用的iconv功能是//TRANSLIT标志,它告诉iconv将没有ASCII匹配的字符转换为最接近的近似字符。

1
音译现在是我今天的口头禅。 - Dolph
4
注意,当语言环境类别 LC_CTYPE 设置为“C”或“POSIX”时,此方法将无法正常工作(您可以使用“echo setlocale(LC_ALL, 0);”查看您的语言环境)。 所有非 ASCII 字符都将转换为“?”。 您需要先将语言环境设置为其他内容:例如,setlocale(LC_ALL, "en_US.UTF-8") - Mike
@Mike 感谢你的提示。如果不是因为你,我可能永远都解决不了那个问题。 - Buttle Butkus
1
如果找不到字符,则用“?”替换该特殊字符。这不应该是最受欢迎的答案,因为它会误导人。 - machineaddict

4
我找到了另一个解决方案,基于@zombat的回答。
他的回答存在问题,我一直得到:
Notice: iconv() [function.iconv]: Wrong charset, conversion from `UTF-8' to `ASCII//TRANSLIT//IGNORE' is not allowed in D:\www\phpcommand.php(11) : eval()'d code on line 3

在从函数中删除//IGNORE后,我得到了:
Gr'a'e~a~o^O"ucisce

所以,字符š被正确翻译了,但其他字符没有。

对我有用的解决方案是使用preg_replace(删除除[a-zA-Z0-9]之外的所有内容,包括空格)和@zombat的解决方案的混合:

preg_replace('/[^a-zA-Z0-9.]/','',iconv('UTF-8', 'ASCII//TRANSLIT', "GráéãõÔücišce"));

输出:

GraeaoOucisce

2

2

我的解决方案是创建两个字符串——第一个包含不需要的字母,第二个包含将替换第一个字符串的字母。

$from = 'čšć';
$to   = 'csc';
$text = 'Gračišće';

$result = str_replace(str_split($from), str_split($to), $text);

3
我真的希望避免自己编写查找表。 - Dolph
@Dolph:现在,这是最接近现实的答案。所有其他答案都会破坏字符串或无法正常运行。 - machineaddict

2

试试这个:

function normal_chars($string)
{
    $string = htmlentities($string, ENT_QUOTES, 'UTF-8');
    $string = preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', $string);
    $string = preg_replace(array('~[^0-9a-z]~i', '~-+~'), ' ', $string);
    return trim($string);
}

Examples:

echo normal_chars('Álix----_Ãxel!?!?'); // Alix Axel
echo normal_chars('áéíóúÁÉÍÓÚ'); // aeiouAEIOU
echo normal_chars('üÿÄËÏÖÜŸåÅ'); // uyAEIOUYaA

根据此线程中所选的答案:如何在PHP中创建URL友好的用户名?


2
+1,但这仅适用于某些情况。例如,“Škoda”变成“Scaron koda”。 - Dolph

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