ruby utf-8

ruby - cuando importamos datos csv, cómo eliminar "secuencia de bytes inválida en UTF-8"



(8)

permitimos a los usuarios importar datos a través de csv (usando ruby ​​1.9.2, por lo tanto, es fastercsv).

al ser datos del usuario, por supuesto, es posible que no se desinfecte adecuadamente.

Cuando tratamos de mostrar los datos en un método / index, a veces obtenemos el error "Secuencia de bytes no válida en UTF-8" apuntando a nuestro erb donde mostramos uno de los campos widget.name

Cuando hacemos la importación, nos gustaría FORZAR que los datos entrantes sean válidos ... ¿hay un operador de ruby ​​que mapeará una cadena a una cadena utf8 válida, por ejemplo, algo así como

goodstring = badstring.no_more_invalid_bytes

Un ejemplo de datos "malos" es "char" que se parece a un guión pero no es un guión ascii regular. Preferiríamos asignar los caracteres no utf-8 a un equivalente ascii razonable (umlat-u yendo a u para exmaple) PERO estamos bien con simplemente despojar al personaje a.

ya que es cuando se importan muchos datos, necesita ser un operador rápido incorporado, con suerte ...

Nota: aquí hay un ejemplo de los datos. El archivo proviene de Windows y es de 8 bits ascii. cuando lo importamos y en nuestro erb mostramos widget.name.inspect (en lugar de widget.name) obtenemos: "Chains / x96 Accessories"

así que un ejemplo de los datos es un "guión" que en realidad es el código 96 de 8 bits.

--- cuando cambiamos nuestro análisis csv para asignar fldval = d.encode (''UTF-8'') arroja este error:

Encoding::UndefinedConversionError in StoresController#importfinderitems "/x96" from ASCII-8BIT to UTF-8

lo que estamos buscando es una forma simple de forzarlo a que sea válido utf8 independientemente del tipo de origen, incluso si simplemente tiramos de no-ascii.

aunque no es tan ''bueno'' como forzar la codificación, esto funciona con un pequeño gasto en nuestro tiempo de importación: d.to_s.strip.gsub (/ / P {ASCII} /, '''') ¡Gracias, Mladen!


Como mencionó otra persona, Scrub funciona bien para limpiar esto en Ruby 2.1+. Si tiene un archivo grande, es posible que no desee leer todo en la memoria, para que pueda usar Scrub como este:

data = IO::read(file_path).scrub("") CSV.parse(data, :col_sep => '','', :headers => true) do |row| puts row end


Respondí una pregunta similar que trata sobre la lectura de archivos externos en 1.9.2 con codificaciones que no son UTF-8. Creo que la respuesta te ayudará mucho: Problema de codificación de caracteres en Rails v3 / Ruby 1.9.2

Tenga en cuenta que necesita saber la codificación fuente para convertir cualquier cosa de manera confiable. Hay bibliotecas como la que he vinculado en mi otra respuesta que puede ayudarlo a determinar esto.

Además, si no está cargando los datos de un archivo, puede convertir la codificación de una cadena en 1.9.2 bastante fácilmente:

''string''.encode(''UTF-8'')

Sin embargo, es raro que esté creando una cadena en otra codificación, y es mejor convertirla en el momento en que se lee en su entorno, si es posible.


Ruby 1.9 CSV tiene un nuevo analizador que funciona con m17n. El analizador funciona con el objeto Encoding of IO en la cadena. Los siguientes métodos: ::foreach, ::open, ::read, and ::readlines podrían ::foreach, ::open, ::read, and ::readlines opciones opcionales :encoding que podría especificar la codificación.

Por ejemplo:

CSV.read(''/path/to/file'', :encoding => ''windows-1251:utf-8'')

Convertiría todas las cadenas a UTF-8.

También puede usar el nombre de codificación más estándar ''ISO-8859-1''

CSV.read(''/..'', {:headers => true, :col_sep => '';'', :encoding => ''ISO-8859-1''})


Ruby 1.9 puede cambiar la codificación de cadena con detección y reemplazo no válidos:

str = str.encode(''UTF-8'', :invalid => :replace)

Para cadenas inusuales, como cadenas cargadas desde un archivo de codificación desconocida, es aconsejable usar #encode en lugar de una expresión regular, #gsub o #delete, ya que todas necesitan la cadena para analizarse, pero si la cadena está rota, no se puede analizar, por lo que esos métodos fallan.

Si recibes un mensaje como este:

error ** from ASCII-8BIT to UTF-8

Entonces probablemente estés tratando de convertir una cadena binaria que ya está en UTF-8, y puedes forzar a UTF-8:

str.force_encoding(''UTF-8'')

Si sabe que la cadena original no está en el UTF-8 binario, o si la cadena de salida tiene caracteres ilegales, entonces lea las transcripciones de la codificación de Ruby.


Si está utilizando Rails , puede intentar arreglarlo con lo siguiente

''Your string with strange stuff #@~''.mb_chars.tidy_bytes

Le quita los caracteres inválidos utf-8 y lo reemplaza con caracteres válidos. Más información: https://apidock.com/rails/String/mb_chars


Solo haz esto

anyobject.to_csv(:encoding => ''utf-8'')


Suba el archivo CSV a la hoja de cálculo de Google Docs y vuelva a descargarlo como un archivo CSV. Importar y ¡voilá! (Funcionó en mi caso)

Presumiblemente Google lo convierte al formato deseado ...

Fuente: Excel a CSV con codificación UTF-8


CSV.parse(File.read(''/path/to/csv'').scrub)