2010-07-01 14 views
10

Actualmente estoy teniendo problemas con los resultados de la API de amazon.cómo convertir la codificación de caracteres con ruby ​​1.9

el servicio devuelve una cadena con caracteres Unicode: Aprender Objetivo \ XE2 \ x80 \ x93C en el Mac (Aprender Series)

con Ruby 1.9.1 la cadena aun no podía sido procesada:

REXML::ParseException: #<Encoding::CompatibilityError: incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)> 

... 

Exception parsing 

Line: 1 

Position: 1636 

Last 80 unconsumed characters: 

Learn Objective–C on the Mac (Learn Series) 
+2

I Recomiendo leer * El mínimo absoluto de cada desarrollador de software Absolutamente, definitivamente debe saber acerca de Unicode y conjuntos de caracteres (Sin excusas!) * (http://www.joelonsoftware.com/articles/Unicode.html), incluso si ya está fa Miliar con codificaciones y tal. – ewall

+2

Recientemente leí el artículo de yehuda katz sobre la codificación en 1.9 y pensé: ¡¿WTF ?! (http://yehudakatz.com/2010/05/17/encodings-unabridged/) el artículo que ha vinculado es excelente. – phoet

Respuesta

29

Como excepción, su cadena tiene codificación ASCII-8BIT. Deberías cambiar la codificación. Hay una long story de eso, pero si usted está interesado en una solución rápida, simplemente force_encoding en la cuerda antes de realizar cualquier proceso:

s = "Learn Objective\xE2\x80\x93C on the Mac" 
# => "Learn Objective\xE2\x80\x93C on the Mac" 
s.encoding 
# => #<Encoding:ASCII-8BIT> 
s.force_encoding 'utf-8' 
# => "Learn Objective–C on the Mac" 
+0

¿es este un problema de la respuesta que se envía desde el servicio Amazon? ¿Debería haber establecido otro tipo de contenido? – phoet

+0

No trabajé con AWS, así que no sé cómo se ha cargado esa cadena, pero puede establecer la codificación predeterminada en el nivel de aplicación (Ruby), por lo que es probable que resuelva el problema, más información sobre el enlace en la respuesta. Por cierto, no creo que haya un _issue_ en absoluto, Ruby simplemente no (y no debería) tratar de adivinar qué codificación está recibiendo la cadena que está recibiendo. –

+0

Probablemente; eso significaría que HTTParty debería encargarse de eso. –

25

solución de Mladen funciona si todo lo que está codificado en ASCII-8BIT realidad se puede convertir directamente a UTF-8. Se rompe cuando hay caracteres que son 1) inválidos, o 2) indefinidos en UTF-8. Sin embargo, esto va a funcionar (en 1.9.2 y hasta:.

new_str = s.encode('utf-8', 'binary', :invalid => :replace, 
    :undef => :replace, :replace => '') 

ASCII-8BIT es efectivamente binaria Este código convierte la codificación UTF-8, mientras que trata correctamente con caracteres no válidos e indefinidos El:. Opción inválida especifica que los caracteres no válidos sean reemplazados. La opción: undef especifica que los caracteres no definidos sean reemplazados. Y la opción: replace define con qué se deben reemplazar los caracteres no válidos o indefinidos. En este caso, opté por simplemente eliminarlos.

+0

uh, se ve bien! lo intentaré! – phoet

+0

¿has probado el mecanismo ': fallback'? Traté de reemplazar algunas codificaciones 'windows-1252' como' u00E4' por ä pero no funcionó :( – phoet

+0

Esto me acaba de salvar el día cuando estoy transfiriendo un archivo a un cuerpo HTTP para publicar ... ¡Muchas gracias! +1 – stuartc

Cuestiones relacionadas