2012-10-18 3 views
32

Nella mia app per rotaie sto lavorando con feed RSS da tutto il mondo e alcuni feed hanno collegamenti che non sono in UTF-8. I link dei feed originali sono fuori dal mio controllo e, per poterli utilizzare in altre parti dell'app, devono essere in UTF-8.Forza le stringhe a UTF-8 da qualsiasi codifica

Come posso rilevare la codifica e convertire in UTF-8?

+0

Per rilevare una codifica, è necessario analizzare le informazioni meta di accompagnamento dei documenti, vale a dire le intestazioni HTTP o '' tag. – deceze

risposta

48

Ruby 1.9

"forzatura" una codifica è facile, tuttavia non converte i caratteri basta cambiare la codifica:

str = str.force_encoding("UTF-8") 

str.encoding.name # => 'UTF-8' 

Se si desidera eseguire una conversione, utilizzare encode:

begin 
    str.encode("UTF-8") 
rescue Encoding::UndefinedConversionError 
    # ... 
end 

avrei sicuramente leggere il seguente post per ulteriori informazioni:
http://graysoftinc.com/character-encodings/ruby-19s-string

+0

grazie per la risposta, l'articolo è stato anche una buona lettura. –

+0

Non funziona: whois = whois.force_encoding ("UTF-8") \ n whois.encoding.name => "UTF-8" \ n whois.scan (/ ruolo: \ s + (. +)/i) - Throws: ArgumentError: sequenza di byte non valida in UTF-8 – Hackeron

+0

Come detto, force_encoding non converte i caratteri e sicuramente non può interpretare magicamente sequenze di byte UTF-8 non valide. – kwarrick

4

Iconv

require 'iconv' 
i = Iconv.new('UTF-8','LATIN1') 
a_with_hat = i.iconv("\xc2") 

Sintesi: la gemma iconv fa tutto il lavoro di conversione di codifiche. Assicurarsi che sia installato con:

gem install iconv 

Ora, è necessario sapere che cosa codifica la stringa è attualmente in Ruby 1.8 tratta le stringhe come un array di byte (. Senza codifica intrinseca) Ad esempio, dire che la stringa di stato in latin1 e si voleva convertirlo in utf-8

require 'iconv' 

string_in_utf8_encoding = Iconv.conv("UTF8", "LATIN1", string_in_latin1_encoding) 
+0

Grazie per la risposta, ma nel mio caso i dati di origine sono incoerenti e non ho un metodo affidabile per annullare le codifiche –

+4

Iconv non dovrebbe più essere usato. (deprecato) http://stackoverflow.com/questions/8148762/iconv-deprecation-warning-with-ruby-1-9-3 – basgys

21

Questo farà sì avete la codifica corretta e non eseguirà l'errore perché sostituisce qualsiasi carattere non valido o non definito con una stringa vuota.

Questo assicurerà non importa cosa, che si dispone di una stringa UTF-8 valida

str.encode(Encoding.find('UTF-8'), {invalid: :replace, undef: :replace, replace: ''})