2011-02-01 17 views
34

sto tirando testo da siti remoti e cercando di caricarlo in una Ruby 1.9/Rails 3 app che utilizza UTF-8 per impostazione predefinita.Convert caratteri non ASCII da ASCII-8BIT a UTF-8

Ecco un esempio di un testo incriminato:

sguardi
Cancer Res; 71(3); 1-11. ©2011 AACR.\n 

Quel codice Copyright ampliato come questo:

Cancer Res; 71(3); 1-11. \xC2\xA92011 AACR.\n 

Rubino mi dice che stringa viene codificato come ASCII-8 bit e l'alimentazione nel mio App Rails mi ottiene questo:

incompatible character encodings: ASCII-8BIT and UTF-8 

Posso spogliare il codice di copyright fuori usando questo Gex

str.gsub(/[\x00-\x7F]/n,'?') 

per produrre questo

Cancer Res; 71(3); 1-11. ??2011 AACR.\n 

Ma come posso ottenere un simbolo di copyright (e vari altri simboli come lettere greche) convertito negli stessi simboli in UTF-8? Sicuramente è possibile ...

vedo riferimenti a utilizzare force_encoding, ma questo non funziona:

str.force_encoding('utf-8').encode 

Mi rendo conto che ci sono molte altre persone con problemi simili, ma ho ancora vedere una soluzione che lavori.

+1

Come si tira il testo dai siti remoti? Scraping pagine? Si prega di mostrare alcuni esempi di codice, incluso il client HTTP che si sta utilizzando, e se si sta analizzando le pagine usando Nokogiri, Hpricot o ReXML. Questo problema potrebbe essere il risultato di come stai recuperando la pagina e/o di come stai analizzando la pagina. Una volta che sappiamo che stai estraendo il contenuto in modo sicuro dai dati, possiamo aiutarti a convertire i dati tra i set di codici. –

+0

Codice semplice reale - open-uri e nokogiri - ad es. doc = Nokogiri :: XML (open (url)) quindi doc.css (...). text per estrarre i blocchi di testo rilevanti –

+1

Si prega di mostrare il codice di esempio. Il file che stai recuperando è HTML o XML? Nokogiri si preoccupa della differenza quando analizza. Inoltre, fornire alcuni URL, perché ogni sito su Internet è diverso. –

risposta

54

questo funziona per me:

#encoding: ASCII-8BIT 
str = "\xC2\xA92011 AACR" 
p str, str.encoding 
#=> "\xC2\xA92011 AACR" 
#=> #<Encoding:ASCII-8BIT> 

str.force_encoding('UTF-8') 
p str, str.encoding 
#=> "©2011 AACR" 
#=> #<Encoding:UTF-8> 
+0

Grazie! Questo è stato molto utile. – Mike

+5

Ciò potrebbe causare l'errore 'sequenza byte non valida in UTF-8'. Ti suggerisco di usare 'encode ('UTF-8')' invece. – jpemberthy

+0

Questo funziona anche per me, ma le altre stringhe no. Ad esempio: str = "Diario El d \ xEDa Bolivia" non si convertirà in "Diario El día Bolivia". –

6

ho usato per fare questo per uno script che raschiato pagine greca di Windows-codificati, utilizzando l'open-uri, iconv e Hpricot:

doc = open(DATA_URL) 
doc.rewind 
data = Hpricot(Iconv.conv('utf-8', "WINDOWS-1253", doc.readlines.join("\n"))) 

credo che era di ruby ​​1.8.7, non so come stanno le cose con ruby ​​1.9

+0

Grazie! Nessuno dei precedenti gestiva "\ x96" per me, sarebbe comunque saltato in aria. Iconv.conv ('utf- 8 ', "WINDOWS-1253", str) ha funzionato perfettamente – spilliton

+0

Potrebbe anche essere necessario impostare il valore di 'traslitterato' di Iconv su true. Http://ruby-doc.org/stdlib-1.9.2/libdoc/iconv/rdoc /Iconv.html#method-i-transliterate-3D – wmarbut

23

ci sono due possibilità:

  1. I dati di input è già UTF-8, ma solo di Ruby non lo sa. Questo sembra essere il tuo caso, poiché "\ xC2 \ xA9" è UTF-8 valido per il simbolo del copyright. Nel qual caso devi dire a Ruby che i dati sono già UTF-8 usando force_encoding.

    Ad esempio "\ xC2 \ xA9" .force_encoding ('ASCII-8BIT') ricreare il bit pertinente dei dati di input. E "\ xC2 \ xA9" .force_encoding ('ASCII-8BIT'). Force_encoding ('UTF-8') dimostrerebbe che puoi dire a Ruby che è davvero UTF-8 e ottenere il risultato desiderato.

  2. dati L'ingresso è in qualche altra codifica e avete bisogno di Ruby di transcodificare a UTF-8. In questo caso dovresti dire a Ruby qual è la codifica corrente (ASCII-8BIT è ruby-speak per binario, non è una vera codifica), quindi di 'a Ruby di transcodificarlo.

    Per esempio, dicono i dati di input è stato ISO-8859-1. In questa codifica il simbolo del copyright è solo "\ xA9". Questo genera una tale bit di dati: "\ xA9" .force_encoding ('ISO-8859-1') e questo dimostrerebbe che è possibile ottenere Ruby per transcodificare che in UTF-8: "\ xA9" .force_encoding ('ISO -8.859-1').encode ('UTF-8')

+0

Stavo ricevendo questo tipo di errore con rail + server sql. Risolto il problema con l'impostazione "encoding: ISO-8859-1" in database.yml e usando "lating string" .encode ("UTF-8") –

+0

Perfetto. # 2 risolto il mio problema, tirando via Ruby/DBI dal server Sql anche. @Lucas Renan: Grazie per l'heads up su rails/database.yml. Potrei aggiungere i binari più tardi per il sito. – jetimms

Problemi correlati