2011-12-09 9 views
4

私は特別なアクセントや有線記号のない同様のものに、文字列の中に、などéáéíóúÀÉÍÓÚのようなラテン文字を変換する必要があります。irvとRubyインタプリタでIconvが異なるのはなぜですか?

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

私は「test.rb」という名前のファイルがあります:

require 'iconv' 

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

私は予想通り「e」を返す、それが動作IRBにそれらの行を貼り付けます。

実行:

$ ruby test.rb 

私は出力として "?" を取得します。

IはIRB 0.9.5(05/04/13)とRuby 1.8.7(2011-06-30パッチレベル352)[I386-のLinux]を使用しています。

+0

はい、UTF-8としてエンコードされるためthis SO searchを試してみてください。また、デフォルトのシステムエンコーディングです。 私は良い記憶があれば、 "#encoding"という魔法のコメントが1.9で導入されたので、うまくいかないと思います。 私はちょうど試したが動作しません。 – zambotn

答えて

3

のRuby 1.8.7は1.9+のようなマルチバイト文字に精通しているではなかったです。一般に、文字列ではなく文字列を一連のバイトとして扱います。そのような文字をよりよく扱う必要がある場合は、1.9+にアップグレードすることを検討してください。

ジェームズ・グレイは、Ruby 1.8でマルチバイト文字を扱うについてseries of articlesを持っています。私はそれらを読んで時間を取ることを強くお勧めします。それは複雑なテーマなので、彼が数回書いたシリーズ全体を読んでみたいと思うでしょう。

$KCODE = "U" 

ので、あなたが1.8で実行中のコードにそれを追加する必要があります:

はまた、1.8エンコーディングのサポートは$KCODEフラグが設定されている必要があります。ここ

サンプルコードのビットである:

#encoding: UTF-8 

require 'rubygems' 
require 'iconv' 

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

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

puts chars.split('') 
puts chars.split('').join 

ルビー1.8.7(2011-06-30パッチレベル352)[x86_64の-darwin10.7.0]を使用し、IRBでそれを実行して、私が取得:

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 = "\303\251\303\241\303\251\303\255\303\263\303\272\303\200\303\211\303\215\303\223\303\232" 
"\303\251\303\241\303\251\303\255\303\263\303\272\303\200\303\211\303\215\303\223\303\232" 
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 
éáéíóúÀÉÍÓÚ 

出力の9行目で、私はRubyに1.8.7の文字のコンセプトに行を分割するように指示しました。結果として '?'それが出力と何をするべきかを知らなかったことを意味します。ライン10は、Iは、マルチバイト文字が正常に翻訳されることを可能にし、通常の文字列に再構築joinバイトの配列をもたらしており、それが分割すると語りました。ルビー1.9.2を使用して、同じコードを実行

が良く示し、より期待望ましい、行動:

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はsplit('')介して、文字のマルチバイトらしさを維持しました。どちらの場合も、Iconv.iconvは正しいことをした

お知らせ、それが入力された文字に視覚的に類似していたキャラクターを作成しました。先頭のアポストロフィが外れているように見えますが、文字が元々アクセントになっていることを思い出させるためにそこにあります。

は、詳細については、関連の質問に右にあるリンクを参照するか、または[ruby] [iconv]

+0

ありがとう、もう少し分かります!今私は2つの問題があります:最初、私はバージョン「1.8.7上でもソフトウェア*必読*作業を起こさをアップグレードすることはできませんが、二つ目はタイトルにある:私は(代わりに、IRBの) 'ruby'の出力を使用してスクリプトを実行した場合この場合、Iconvは動作しません。第7ラインの – zambotn

+0

そしてまた私の出力が異なっている:私は 'eaeiouAEIOU'代わりに' 'e'a'e'i'o'u \ 'A'E'I'O'U'を持っています。 – zambotn

+0

Ruby 1.9+は自動的に 'require 'rubygems''を実行します。そのため、1.8.7でスクリプトに追加する必要があります。混乱を減らすためにサンプルに追加します。 –

関連する問題