/ / Perché Iconv funziona in modo diverso in irb e nell'interprete Ruby? - rubino, irb, iconv

Perché Iconv funziona in modo diverso in irb e nell'interprete Ruby? - rubino, irb, iconv

Devo convertire caratteri latini come éáéíóúÀÉÍÓÚ ecc., in una stringa di simili simili senza accenti speciali o simboli cablati:

é -> e
è -> e
Ä -> A

Ho un file chiamato "test.rb":

require "iconv"

puts Iconv.iconv("ASCII//translit", "utf-8", "è").join

Quando incollo quelle righe in irb funziona, restituendo "e" come previsto.

In esecuzione:

$ ruby test.rb

Ottengo "?"come output.

Sto usando irb 0.9.5 (05/04/13) e Ruby 1.8.7 (2011-06-30 patchlevel 352) [i386-linux].

risposte:

3 per risposta № 1

Ruby 1.8.7 non era esperto di carattere multibyte come lo è 1.9+. In generale, tratta una stringa come una serie di byte, piuttosto che caratteri. Se hai bisogno di una migliore gestione di tali personaggi, considera l'aggiornamento a 1.9+.

James Gray ha un serie di articoli sulla gestione dei personaggi multibyte in Ruby 1.8. Consiglio vivamente di prenderti il ​​tempo di leggerli. È un argomento complesso, quindi vorrai leggere l'intera serie che ha scritto un paio di volte.

Inoltre, il supporto per la codifica 1.8 richiede $KCODE bandiera impostata:

$KCODE = "U"

quindi dovrai aggiungerlo al codice in esecuzione in 1.8.

Ecco un po 'di codice di esempio:

#encoding: utf-8

require "rubygems"
require "iconv"

chars = "éáéíóúÀÉÍÓÚ"

puts Iconv.iconv("ASCII//translit", "utf-8", chars)

puts chars.split("")
puts chars.split("").join

Usando ruby ​​1.8.7 (2011-06-30 patchlevel 352) [x86_64-darwin10.7.0] ed eseguendolo in IRB, ottengo:

1.8.7 :001 > #encoding: utf-8
1.8.7 :002 >
1.8.7 :003 >   require "iconv"
true
1.8.7 :004 >
1.8.7 :005 >   chars = "303251303241303251303255303263303272303200303211303215303223303232"
"303251303241303251303255303263303272303200303211303215303223303232"
1.8.7 :006 >
1.8.7 :007 >   puts Iconv.iconv("ASCII//translit", "utf-8", chars)
"e"a"e"i"o"u`A"E"I"O"U
nil
1.8.7 :008 >
1.8.7 :009 >   puts chars.split("")
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
nil
1.8.7 :010 > puts chars.split("").join
éáéíóúÀÉÍÓÚ

Alla riga 9 in uscita ho detto a Ruby di dividere il filelinea nel suo concetto di personaggi, che in 1.8.7, era byte. Il risultato "?" significa che non sapeva cosa fare con l'output. Una riga 10 l'ho detto di dividere, il che ha provocato una matrice di byte, che join quindi riassemblato nella stringa normale, permettendo ai caratteri multibyte di essere tradotti normalmente.

L'esecuzione dello stesso codice utilizzando Ruby 1.9.2 mostra un comportamento migliore, più atteso e desiderabile:

1.9.2p290 :001 > #encoding: utf-8
1.9.2p290 :002 >
1.9.2p290 :003 >   require "iconv"
true
1.9.2p290 :004 >
1.9.2p290 :005 >   chars = "éáéíóúÀÉÍÓÚ"
"éáéíóúÀÉÍÓÚ"
1.9.2p290 :006 >
1.9.2p290 :007 >   puts Iconv.iconv("ASCII//translit", "utf-8", chars)
"e"a"e"i"o"u`A"E"I"O"U
nil
1.9.2p290 :008 >
1.9.2p290 :009 >   puts chars.split("")
é
á
é
í
ó
ú
À
É
Í
Ó
Ú
nil
1.9.2p290 :010 > puts chars.split("").join
éáéíóúÀÉÍÓÚ

Ruby ha mantenuto la multibyteità dei personaggi, attraverso il split("").

Si noti che in entrambi i casi, Iconv.iconv ha fatto la cosa giusta, ha creato personaggi cheerano visivamente simili ai caratteri di input. Mentre l'apostrofo principale sembra fuori posto, è lì a ricordare che i personaggi erano stati accentati in origine.

Per ulteriori informazioni, consultare i collegamenti a destra per domande correlate o provare questa ricerca SO per [ruby] [iconv]