2008-11-04 29 views
12

Tengo un script de Ruby que genera un archivo UTF8 CSV de forma remota en una máquina Linux y luego transfiere el archivo a una máquina de Windows a través de SFTP.Conversión de UTF8 a ANSI con Ruby

Necesito abrir este archivo con Excel, pero Excel no tiene UTF8, así que siempre necesito abrir el archivo en un editor de texto que tenga la capacidad de convertir UTF8 a ANSI.

Me encantaría hacer esto programáticamente usando Ruby y evitar el paso de conversión manual. ¿Cuál es la forma más fácil de hacerlo?

PD: Intenté usar iconv pero no tuve éxito.

Respuesta

16
ascii_str = yourUTF8text.unpack("U*").map{|c|c.chr}.join 

asumiendo que su texto realmente encaja en el juego de caracteres ascii.

+0

que lo hizo así y se no necesitó usar iconv en absoluto. ¡Gracias! – Dema

+1

Nota, si 'c' es mayor que 255, fallará (ya que está fuera del rango ASCII). –

+3

Para corregir el error no ASCII con el que se encontró Sam, puede usar lo siguiente: yourUTF8text.unpack ("U *"). Map {| c | c.chr rescue '_'} .join – metavida

13

Finalmente logré hacerlo usando iconv, solo estaba estropeando los parámetros. Entonces, así es como lo haces:


require 'iconv' 

utf8_csv = File.open("utf8file.csv").read 

# gotta be careful with the weird parameters order: TO, FROM ! 
ansi_csv = Iconv.iconv("LATIN1", "UTF-8", utf8_csv).join 

File.open("ansifile.csv", "w") { |f| f.puts ansi_csv } 

Eso es todo!

5

Tuve un problema similar al tratar de generar archivos CSV a partir de contenido generado por el usuario en el servidor. Encontré la gema unidecoder que hace un buen trabajo al transcribir los caracteres Unicode en Ascii.

Ejemplo:

"olá, mundo!".to_ascii     #=> "ola, mundo!" 
"你好".to_ascii      #=> "Ni Hao " 
"Jürgen Müller".to_ascii    #=> "Jurgen Muller" 
"Jürgen Müller".to_ascii("ü" => "ue") #=> "Juergen Mueller" 

Para nuestro caso de uso simple, esto funcionó bien.

Pivotal Labs tiene una gran publicación de blog en unicode transliteration to ascii discutiendo esto con más detalle.

2

Desde Ruby 1.9 hay una manera más fácil:

yourstring.encode('ASCII') 

para evitar problemas con inválida (no ASCII) caracteres que se pueden ignorar los problemas:

yourstring.encode('ASCII', invalid: :replace, undef: :replace, replace: "_") 
Cuestiones relacionadas