utf8_decode utf8 online ruby encoding utf-8 character-encoding iconv

utf8 - La codificación de cadenas de conversión de Ruby de ISO-8859-1 a UTF-8 no funciona



ruby encode utf-8 (2)

Hay una diferencia entre force_encoding y encode . El primero establece la codificación para la cadena, mientras que el último realmente transcodifica el contenido de la cadena a la nueva codificación. En consecuencia, el siguiente código causa su problema:

string = "Norrlandsvägen" string.force_encoding(''iso-8859-1'') puts string.encode(''utf-8'') # Norrlandsvägen

Mientras que el siguiente código en realidad codificará correctamente sus contenidos:

string = "Norrlandsvägen".encode(''iso-8859-1'') string.encode!(''utf-8'')

Aquí hay un ejemplo que se ejecuta en irb :

irb(main):023:0> string = "Norrlandsvägen".encode(''iso-8859-1'') => "Norrlandsv/xE4gen" irb(main):024:0> string.encoding => #<Encoding:ISO-8859-1> irb(main):025:0> string.encode!(''utf-8'') => "Norrlandsvägen" irb(main):026:0> string.encoding => #<Encoding:UTF-8>

Estoy tratando de convertir una cadena de codificación ISO-8859-1 a UTF-8, pero parece que no puedo hacer que funcione. Aquí hay un ejemplo de lo que hice en irb.

irb(main):050:0> string = ''Norrlandsvägen'' => "Norrlandsvägen" irb(main):051:0> string.force_encoding(''iso-8859-1'') => "Norrlandsv/xC3/xA4gen" irb(main):052:0> string = string.encode(''utf-8'') => "Norrlandsvägen"

No estoy seguro de por qué Norrlandsvägen en iso-8859-1 se convertirá en Norrlandsvägen en utf-8.

He intentado codificar, codificar, codificar (destinationEncoding, originalEncoding), iconv, force_encoding y todo tipo de soluciones de trabajo extrañas en las que podía pensar pero nada parece funcionar. ¿Puede alguien ayudarme / señalarme en la dirección correcta?

Novato Ruby todavía tirando del pelo como loco, pero sintiéndose agradecido por todas las respuestas aquí ... :)

Antecedentes de esta pregunta: estoy escribiendo una joya que descargará un archivo xml de algunos sitios web (que tendrá la codificación iso-8859-1) y lo guardará en un almacenamiento y me gustaría convertirlo primero a utf-8. Pero las palabras como Norrlandsvägen siguen arruinándome. ¡Realmente cualquier ayuda sería muy apreciada!

[ACTUALIZACIÓN]: me di cuenta de que ejecutar pruebas como esta en la consola irb podría darme comportamientos diferentes, así que esto es lo que tengo en mi código actual:

def convert_encoding(string, originalEncoding) puts "#{string.encoding}" # ASCII-8BIT string.encode(originalEncoding) puts "#{string.encoding}" # still ASCII-8BIT string.encode!(''utf-8'') end

pero la última línea me da el siguiente error:

Encoding::UndefinedConversionError - "/xC3" from ASCII-8BIT to UTF-8

Gracias a la respuesta de /xC3 continuación, noté que /xC3 aparece realmente en irb si ejecutas:

irb(main):001:0> string = ''ä'' => "ä" irb(main):002:0> string.force_encoding(''iso-8859-1'') => "/xC3/xA4"

También traté de asignar una nueva variable al resultado de string.encode(originalEncoding) pero obtuve un error aún más extraño:

newString = string.encode(originalEncoding) puts "#{newString.encoding}" # can''t even get to this line... newString.encode!(''utf-8'')

y el error es Encoding::UndefinedConversionError - "/xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to ISO-8859-1

Todavía estoy bastante perdido en todo este lío de codificación, pero estoy muy agradecido por todas las respuestas y la ayuda que todos me han brindado. ¡Gracias una tonelada! :)


Usted asigna una cadena, en UTF-8. Contiene ä . UTF-8 representa ä con dos bytes.

string = ''ä'' string.encoding # => #<Encoding:UTF-8> string.length # 1 string.bytes # [195, 164]

Luego, fuerza los bytes a interpretar como si fueran ISO-8859-1, sin cambiar realmente la representación subyacente. Esto ya no contiene ä . Contiene dos caracteres, Ã y ¤ .

string.force_encoding(''iso-8859-1'') # => "/xC3/xA4" string.length # 2 string.bytes # [195, 164]

Luego lo UTF-8 en UTF-8 . Como esto no es una reinterpretación sino una traducción, mantienes los dos caracteres, pero ahora está codificado en UTF-8:

string = string.encode(''utf-8'') # => "ä" string.length # 2 string.bytes # [195, 131, 194, 164]

Lo que te falta es el hecho de que originalmente no tienes una cadena ISO-8859-1, como lo harías con tu servicio web; tienes un galimatías. Afortunadamente, esto es todo en tus pruebas de consola; si lee la respuesta del sitio web utilizando la codificación de entrada adecuada, todo debería funcionar bien.

Para su prueba de consola, demostremos que si comienza con una cadena ISO-8859-1 adecuada, todo funciona:

string = ''Norrlandsvägen''.encode(''iso-8859-1'') # => "Norrlandsv/xE4gen" string = string.encode(''utf-8'') # => "Norrlandsvägen"

EDITAR Para su problema específico, esto debería funcionar:

require ''net/https'' uri = URI.parse("https://rusta.easycruit.com/intranet/careerbuilder_se/export/xml/full") options = { :use_ssl => uri.scheme == ''https'', :verify_mode => OpenSSL::SSL::VERIFY_NONE } response = Net::HTTP.start(uri.host, uri.port, options) do |https| https.request(Net::HTTP::Get.new(uri.path)) end body = response.body.force_encoding(''ISO-8859-1'').encode(''UTF-8'')