如何在PHP中替换变音字符或Unaccent?

时间:2012-10-11 06:18:47

标签: php character-encoding diacritics

我有一个名字“Göran”,我希望将其转换为“ Goran ”,这意味着我需要 unaccent 特定的词。但我所尝试的似乎并非 unaccent 所有单词。

这是我用于Unaccent的代码:

private function Unaccent($string)
{
    return preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml|caron);~i', '$1', htmlentities($string, ENT_COMPAT, 'UTF-8'));
}

不工作的地方(不正确的匹配):我的意思是它没有在右侧给出预期的结果,

JÃŒrgen => Juergen
InÚs => Ines

它正在工作的地方(正确匹配):

Göran => Goran
Jørgen Ole => Jorgen
Jérôme => Jerome

可能是什么原因?怎么修?你有更好的办法处理所有案件吗?

2 个答案:

答案 0 :(得分:4)

这可能就是你要找的东西

How to convert special characters to normal characters?

但请改用“utf-8”。

$text = iconv('utf-8', 'ascii//TRANSLIT', $text);

http://us2.php.net/manual/en/function.iconv.php

答案 1 :(得分:2)

简短回答

你有两个问题:

首先。这些名称没有重音。它们格式错误。

您似乎有一个UTF-8文件,但正在使用ISO-8559-1进行处理。例如,如果您告诉编辑器使用ISO-8859-1并使用UTF-8将文本复制粘贴到浏览器的文本区域中。然后,您将格式错误的名称保存在数据库中。我看到很多这样的问题都是由复制粘贴引起的。

如果名称格式正确,那么您可以解决第二个问题。让他们不高兴。对此有一个问题:How to convert special characters to normal characters?

答案很长(仅关注格式错误的重音字母)

为什么在需要Göran

时才能获得Göran

让我们从Unicode开始:字母ö是Unicode LATIN SMALL LETTER O WITH DIAERESIS。其Unicode代码点为F6十六进制或分别为246十进制。请参阅Unicode link到Unicode数据库。

在ISO-8859-1中,0到255的代码点保持原样。带有分音符的小写字母o仅保存为一个字节:246。

UTF-8和ISO-8859-1将代码点0到127(也称为ASCII)视为相同。它们保持原样并保存为仅一个字节。它们在代码点128到255的处理方面有所不同.UTF-8可以编码整个Unicode代码点集,而ISO-8859-1只能处理前256个代码点。

那么,UTF-8对128以上代码点的作用是什么?随着代码点变得越来越大,代码点有一组交错的编码可能性。对于高达2047的代码点,两个字节就足够了。它们编码如下:(see this bit schema

x xxxx xxxx xxxx => 110xxxxx 10xxxxxx

让我们用UTF-8中的diaresis编码小写字母o。这些位是:0 0000 1111 0110并被编码为11000011 10110110。这很好。

但是,这两个字节可能被误解为两个有效(!)ISO-8559-1字节。什么是11000011(C3 hex)和10110110(B6 hex)?我们来咨询an ISO-8859-1 table。 C3是Capital A代字号,B6是Paragraph符号。这两个标志都是有效的,没有软件可以通过查看位来检测这种误解。

明确需要知道名字的人。 Göran不是名字。名称中间有一个大写字母,段落符号根本不是字母。可悲的是,这种误解并不止于此。由于所有字符都有效,因此可以对它们进行复制粘贴和重新渲染。在这个过程中,误解可以再次重复。让我们用Göran来做这件事。我们已经误解了一次并且格式错误Göran。字母Capital A,代字号和段落符号呈现为UTF-8中的两个字节每个(!),并被解释为gobbledygook的四个字节,类似于GÃÅ.ran

可怜的Jürgen!变音符ü被误治了两次,我们有JÃŒrgen

我们这里的变音符号很糟糕。 OP甚至可能从他的客户那里得到这些数据。这件事发生在我身上:我得到了混合数据:格式良好,格式错误,一次,两次和三次在同一个文件中。这非常令人沮丧。