gpt4 book ai didi

ruby - 为什么 Iconv 在 irb 和 Ruby 解释器中的工作方式不同?

转载 作者:数据小太阳 更新时间:2023-10-29 07:34:47 25 4
gpt4 key购买 nike

我必须将 éáéíóúÀÉÍÓÚ 等拉丁字符转换为类似的字符串,而无需特殊重音符号或有线符号:

é -> 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 补丁级别 352)[i386-linux]。

最佳答案

Ruby 1.8.7 不像 1.9+ 那样精通多字节字符。通常,它将字符串视为一系列字节,而不是字符。如果您需要更好地处理此类字符,请考虑升级到 1.9+。

James Gray 有一个 series of articles关于在 Ruby 1.8 中处理多字节字符。我强烈建议您花时间通读它们。这是一个复杂的主题,因此您需要多次阅读他写的整个系列。

此外,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 都做了正确的事情,它创建的字符在视觉上与输入字符相似。虽然前导撇号看起来不合适,但它的存在是为了提醒这些字符最初是重音符号。

有关更多信息,请参阅相关问题右侧的链接或尝试this SO search对于 [ruby] [iconv]

关于ruby - 为什么 Iconv 在 irb 和 Ruby 解释器中的工作方式不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8445788/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com