我必须将像éáéíóúÀÉÍÓÚ
等拉丁字符转换为字符串,而不是特殊的重音或有线符号的字符串:
é -> 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 :(得分:3)
Ruby 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
使用ruby 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
éáéíóúÀÉÍÓÚ
Ruby通过split('')
保持字符的多字节。
请注意,在这两种情况下,Iconv.iconv
做了正确的事情,它创建了与输入字符在视觉上相似的字符。虽然领先的撇号看起来不合适,但它提醒人们最初对角色进行了重音。
有关详细信息,请参阅相关问题右侧的链接或尝试使用[ruby] [iconv]
{{1}}