2011-12-09 60 views
4

我不得不拉丁字符轉換像éáéíóúÀÉÍÓÚ等,轉換成字符串類似那些無特殊口音或有線符號:爲什麼Iconv在irb和Ruby解釋器中工作不同?

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

我有一個文件名爲「test.rb」:

require 'iconv' 

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

當我將這些行粘貼到irb中時,它會按預期返回「e」。

運行:

$ ruby test.rb 

我得到 「?」 作爲輸出。

我使用irb 0.9.5(05/04/13)和Ruby 1.8.7(2011-06-30 patchlevel 352)[i386-linux]。

+0

是,被編碼成UTF-8。它也是默認的系統編碼。 我覺得它也行不通,因爲如果我有良好的記憶力,1.9版本中就會引入「#encoding」魔術評論。 雖然我剛剛嘗試過,但不起作用。 – zambotn

回答

3

紅寶石1.8.7不是像1.9+是多字節字符精明。通常,它將字符串視爲一系列字節,而不是字符。如果您需要更好地處理這些角色,請考慮升級到1.9+。

James Gray有一個關於在Ruby 1.8中處理多字節字符的series of articles。我強烈建議花時間閱讀它們。這是一個複雜的主題,所以你需要閱讀他編寫的整個系列。

此外,1.8編碼的支持需要$KCODE標誌設置:

$KCODE = "U" 

所以你需要將它添加到代碼運行在1.8。

這裏是一個比特的示例代碼:

#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 PATCHLEVEL 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行產生了一個字節數組,然後join重新組裝成普通字符串,從而允許多字節字符正常轉換。

運行使用Ruby 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 
éáéíóúÀÉÍÓÚ 

紅寶石保持的字符的多字節岬,通過split('')

請注意,在這兩種情況下,Iconv.iconv都做得對,它創建的視覺效果與輸入字符相似。雖然主要的撇號看起來不合適,但它在那裏提醒人物原本是重音符號。

欲瞭解更多信息,請參見右側的鏈接到相關的問題或嘗試this SO search[ruby] [iconv]

+0

好,非常感謝你,我明白了一點!現在我有兩個問題:第一,我不能升級版本,因爲軟件必須工作在1.8.7上,第二個是標題:如果我用'ruby'(而不是IRB)運行你的腳本,輸出不同,似乎Iconv在這種情況下不起作用。 – zambotn

+0

而且我的第七行的輸出是不同的:我有'eaeiouAEIOU'而不是''e'a'e'i'o'u''E'I'O'U'。 – zambotn

+0

Ruby 1.9+自動執行'require'rubygems'',所以您需要將它添加到1.8.7的腳本中。我會將其添加到我的示例中以減少混淆。 –

相關問題