iconv дает «Незаконный персонаж» с умными цитатами - как от них избавиться? - PullRequest
7 голосов
/ 26 мая 2009

У меня есть таблица MySQL с 120000 строк, хранящихся в формате UTF-8. Есть одно поле, название продукта, которое содержит текст с множеством акцентов. Мне нужно заполнить второе поле с тем же именем после преобразования его в форму, удобную для URL (ASCII).

Поскольку PHP напрямую не обрабатывает UTF-8, я использую:

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

для преобразования имени в ISO-8859-1, за которым следует массивный оператор strstr для замены любого акцентированного символа его безударным эквивалентом (например, становится a).

Тем не менее, оригинальные текстовые имена были введены с умными кавычками, и iconv задыхается всякий раз, когда он сталкивается с одним - я получаю:

Unknown error type: [8]

iconv() [function.iconv]: Detected an illegal character in input string

Чтобы избавиться от умных кавычек перед использованием iconv, я попытался использовать три утверждения, такие как:

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

(- это необработанное значение умной одинарной кавычки UTF-8)

Поскольку текстовый файл очень длинный, эти str_replace приводят к тому, что время ожидания скрипта истекает каждый раз.

  1. Какой самый быстрый способ вырезать умные кавычки (или любые недопустимые символы) из строки UTF-8 перед запуском iconv?

  2. Или, есть ли более простое решение всей этой проблемы? Какой самый быстрый способ преобразовать имя с множеством акцентов в UTF-8 в имя без акцентов, написанное правильно, в ASCII?

Ответы [ 3 ]

6 голосов
/ 28 мая 2009

Glibc (и GNU libiconv ) поддерживает суффиксы //TRANSLIT и //IGNORE.

Таким образом, в Linux это работает просто отлично:

$ echo $'\xe2\x80\x99'
’
$ echo $'\xe2\x80\x99' | iconv -futf8 -tiso8859-1
iconv: illegal input sequence at position 0
$ echo $'\xe2\x80\x99' | iconv -futf8 -tiso8859-1//translit
'

Я не уверен, что iconv используется PHP, но из документации следует, что //TRANSLIT и //IGNORE также будут работать там.

2 голосов
/ 26 мая 2009

Что вы подразумеваете под "дружественным к ссылкам"? Единственный способ, который имеет смысл для меня, поскольку текст между тегами <a>...</a> может быть любым, на самом деле «дружественный к URL», аналогичен URL-адресам SO, где все преобразуется в [a-z-].

Если это то, что вам нужно, вам понадобится библиотека транслитерации, а не библиотека преобразования наборов символов. (Мне не повезло получить iconv () для выполнения работы в прошлом, но я не пробовал некоторое время.) Есть бета-расширение PHP translit , которое , вероятно, делает эту работу .

Если вы не можете добавить расширения к вашей установке PHP, вам придется искать библиотеку PHP, которая делает то же самое. Я не использовал его, но библиотека PHP UTF-8 реализует библиотеку utf8_to_ascii, которая, как я полагаю, делает то, что вам нужно.

(Кроме того, если iconv () завершается с ошибкой, как вы сказали, это означает, что ваш ввод на самом деле не является допустимым UTF-8, поэтому никакие замены действительного UTF-8 чем-либо другим не помогут в решении проблемы. РЕДАКТИРОВАТЬ: I может принять это обратно: если ответ ephemient правильный, ошибка iconv, которую вы видите, вполне может быть связана с тем, что в наборе символов назначения нет прямого представления символа. Итак, не обращайте внимания.)

0 голосов
/ 27 мая 2009

Рассматривали ли вы использование строковой функции MySQL REPLACE для преобразования поврежденных строк в апострофы или что-то еще? Возможно, вам удастся собрать часть «заменяемая строка», например, используя CONCAT на CHAR вызовах ...

...