2009-05-26 20 views
7

Tengo una tabla MySQL con 120,000 líneas almacenadas en formato UTF-8. Hay un campo, nombre de producto, que contiene texto con muchos acentos. Necesito completar un segundo campo con este mismo nombre después de convertirlo a un formato amigable para las URL (ASCII).iconv da "carácter ilegal" con comillas inteligentes: ¿cómo deshacerse de ellas?

A partir de PHP no maneja directamente UTF-8, que estoy usando:

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

para convertir el nombre de la norma ISO-8859-1, seguido de una declaración masiva strstr para reemplazar cualquier carácter acentuado por su equivalente no acentuado (à se convierte en a, por ejemplo).

Sin embargo, los nombres de texto originales se introdujeron con citas inteligentes, y iconv ahoga cada vez que viene a través de uno - me sale:

 
Unknown error type: [8] 

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

para deshacerse de las comillas tipográficas antes de utilizar iconv, he tratado utilizando tres afirmaciones como:

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

(â € ™ es el valor bruto de un inteligente comilla simple UTF-8)

Debido a que el archivo de texto es tan largo, la causa de estos str_replace º e script para el tiempo de espera cada vez.

  1. ¿Cuál es la manera más rápida que se deben eliminar las comillas tipográficas (o caracteres no válidos) de una cadena UTF-8, antes de ejecutar iconv?

  2. ¿O existe una solución más fácil a todo este problema? ¿Cuál es la forma más rápida de convertir un nombre con muchos acentos, en UTF-8, en un nombre sin acentos, escrito correctamente, en ASCII?

+2

¿Has probado iconv() // capacidad de TRANSLIT fuera? Debe convertir los caracteres acentuados en sus equivalentes ASCII legibles. – ceejayoz

+0

Estoy viendo la documentación, pero no veo cómo ayudará: si iconv() ya se ahoga en una cita inteligente, ¿no se ahogará todavía si uso // TRANSLIT? –

+0

Esto es más para su "declaración masiva strstr" - es por eso que hice un comentario en lugar de una respuesta. – ceejayoz

Respuesta

2

¿Qué quiere decir con "link-friendly"? La única forma que tiene sentido para mí, ya que el texto entre las etiquetas <a>...</a> puede ser cualquier cosa, es realmente "compatible con las URL", similar a las URL de SO donde todo se convierte en [a-z-].

Si eso es lo que está buscando, necesitará una biblioteca de transliteración, no una biblioteca de conversión de juegos de caracteres. (No he tenido suerte haciendo que iconv() haga el trabajo en el pasado, pero no lo he intentado en un tiempo). Hay una extensión beta de PHP translit que probably does the job.

Si no puede agregar extensiones a su instalación PHP, tendrá que buscar una biblioteca PHP que haga lo mismo. No lo he usado, pero la biblioteca PHP UTF-8 implementa una biblioteca utf8_to_ascii que, supongo, hace algo así como lo que necesita.

(Además, si iconv() está fallando como usted dijo, significa que su entrada no es realmente válida UTF-8, por lo que ninguna cantidad de reemplazo de UTF-8 válido con algo más ayudará al problema. Puedo recuperarlo: si ephemient's answer es correcto, el error de iconv que está viendo puede deberse a que no hay representación directa del personaje en el conjunto de caracteres de destino. Así que, no importa.)

+0

Cambié la pregunta para leer amigable para la url. No puedo agregar extensiones a PHP. Revisé la biblioteca translit que sugieres, pero fue aproximadamente un 35% más lenta que mi solución original. –

0

¿Ha considerado usar MySQL? REPLACE función de cadena para cambiar las cadenas ofensivas en apóstrofos, o lo que sea? Puede armar la parte "cadena a reemplazar", p. usando CONCAT en CHAR llamadas ...

+0

Comencé usando str_replace para reemplazar las cadenas ofensivas, pero ralentizaba demasiado la secuencia de comandos ($ value = str_replace ('â' ™ ', "' '', $ value); donde 'es la representación asci de la ofender simple cita inteligente). ¿Puedes aclarar qué quieres decir con CONCAT en las llamadas CHAR? –

+0

Sugerí hacer el REEMPLAZO en SQL, y usar CONCAT (CHAR (...), ... para componer la subcadena que está tratando de reemplazar, byte por byte. –

6

Glibc (y la GNU libiconv) supports//TRANSLIT y //IGNORE sufijos.

Por lo tanto, en Linux, esto funciona muy bien:

 
$ 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 
' 

No estoy seguro de lo que iconv está en uso por PHP, pero la documentación, que //TRANSLIT y //IGNORE funcionará allí también.

Cuestiones relacionadas