7

我有一个 MySQL 表,其中 120,000 行以 UTF-8 格式存储。有一个字段,产品名称,其中包含带有许多重音符号的文本。在将第二个字段转换为对 url 友好的表单 (ASCII) 后,我需要用相同的名称填充第二个字段。

由于 PHP 不直接处理 UTF-8,我正在使用:

$value = iconv ('UTF-8', 'ISO-8859-1', $value);

将名称转换为 ISO-8859-1,然后是一个庞大的 strstr 语句,将任何重音字符替换为其非重音等效字符(例如,à 变为 a)。

但是,原始文本名称是用智能引号输入的,并且 iconv 遇到一个就会窒息——我得到:

未知错误类型:[8]

iconv() [function.iconv]:在输入字符串中检测到非法字符

为了在使用 iconv 之前摆脱智能引号,我尝试使用三个语句,例如:

$value = str_replace('’', "'", $value);

(’ 是 UTF-8 智能单引号的原始值)

因为文本文件太长,这些 str_replace 会导致脚本每次都超时。

  1. 在运行 iconv 之前,从 UTF-8 字符串中去除智能引号(或任何无效字符)的最快方法是什么?

  2. 或者,是否有更简单的解决方案来解决整个问题?将 UTF-8 中具有多种重音符号的名称转换为 ASCII 中没有重音符号且拼写正确的名称的最快方法是什么?

4

3 回答 3

6

Glibc(和 GNU libiconv支持 //TRANSLIT//IGNORE后缀。

因此,在 Linux 上,这工作得很好:

$ 回声 $'\xe2\x80\x99'
'
$ 回声 $'\xe2\x80\x99' | iconv -futf8 -tiso8859-1
iconv:位置 0 处的非法输入序列
$ 回声 $'\xe2\x80\x99' | iconv -futf8 -tiso8859-1//translit
'

我不确定iconvPHP 使用的是什么,但文档暗示了这一点,//TRANSLIT并且//IGNORE也将在那里工作。

于 2009-05-28T17:32:42.067 回答
2

“链接友好”是什么意思?唯一对我有意义的方法,因为<a>...</a>标签之间的文本可以是任何东西,实际上是“URL友好的”,类似于 SO 的 URL,其中所有内容都转换为[a-z-].

如果这就是您想要的,您将需要一个音译库,而不是字符集转换库。(过去我没有运气让 iconv() 完成这项工作,但我有一段时间没有尝试过。)有一个 beta PHP 扩展translit可能可以完成这项工作

如果你不能为你的 PHP 安装添加扩展,你将不得不寻找一个 PHP 库来做同样的事情。我没有使用它,但是PHP UTF-8库实现了一个utf8_to_ascii库,我认为它可以满足您的需求。

(另外,如果 iconv() 像你说的那样失败,这意味着你的输入实际上不是有效的 UTF-8,所以用其他任何东西替换有效的 UTF-8 都不会解决这个问题。编辑:我可能会接受返回:如果ehemient 的答案是正确的,那么您看到的 iconv 错误很可能是因为目标字符集中没有直接表示该字符。所以,没关系。)

于 2009-05-26T17:55:00.270 回答
0

您是否考虑过使用 MySQL 的REPLACE字符串函数将有问题的字符串更改为撇号或其他?您也许可以将“要替换的字符串”部分放在一起,例如通过使用CONCAT通话CHAR...

于 2009-05-27T01:54:48.947 回答