2

ARGF.set_encoding说:

如果指定了单个参数,则从 ARGF 读取的字符串将使用指定的编码进行标记。

如果给出了用冒号分隔的两个编码名称,例如“ascii:utf-8”,则读取的字符串从第一个编码(外部编码)转换为第二个编码(内部编码),然后用第二个编码标记。

所以我尝试了以下方法:

p RUBY_VERSION
p ARGF.external_encoding
ARGF.set_encoding('ascii')
p ARGF.readlines($/)

输出:

D:\Rubyscript\My ruby learning days>ruby true.rb a.txt
"2.0.0"
#<Encoding:IBM437>
["Hi! How are you?\n", "I am doing good,thanks."]

p RUBY_VERSION
p ARGF.external_encoding
ARGF.set_encoding(ARGF.external_encoding,'ascii')
p ARGF.readlines($/)

输出:

D:\Rubyscript\My ruby learning days>ruby true.rb a.txt
"2.0.0"
#<Encoding:IBM437>
["Hi! How are you?\n", "I am doing good,thanks."]

未发现编码更改。所以请告诉我正确的方法。

4

1 回答 1

5

编码IBM437ASCII(和UTF-8)对于 ASCII 字符具有相同的字节序列。所以你不会看到与 的区别String#inspect。但是,您可以检查String#encoding输入字符串的值。

p RUBY_VERSION
p ARGF.external_encoding
ARGF.set_encoding(ARGF.external_encoding,'ascii')
p ARGF.readlines($/).map{|s| s.encoding}

在 Ruby(1.9 及更高版本)中,String 是带有某种编码标记的字节序列。您可以从中获取编码String#encoding

所以中文单词“中”可以用不同的方式表示:

e4 b8 ad          # tagged with encoding UTF-8
d6 d0             # tagged with encoding GBK
2d 4e             # tagged with encoding UTF-16le

我将始终使用 UTF-8 编写我的脚本,也就是说,我的脚本的内部编码是 UTF-8。有时我想处理用 GBK 编码的文本文件(例如,名为“a.txt”并且内容为“中”)。然后我可以为 IO 对象设置外部编码和内部编码,Ruby 将为我进行转换。

ARGF.set_encoding('GBK', 'UTF-8')
str = ARGF.readline
puts str.encoding

# run             $ script.rb a.txt

Ruby"\xd6\xd0"从“a.txt”中读取数据,并且由于我已将外部编码指定为 GBK,因此它使用编码 GBK 标记数据。而且我已将内部编码指定为 UTF-8,因此 Ruby 将 GBK 字节序列转换为 UTF-8,从而产生"\xe4\xb8\xad"标记 UTF-8。而且这个字符串与我脚本中的其他字符串具有相同的编码,所以我可以轻松使用它。

这很有用,因为当两个 String 操作数具有不同的、不兼容的编码时,许多 String 方法都会失败。例如:

# encoding: utf-8
a = "中"                  # tagged with UTF-8
b = "中".encode('gbk')    # tagged with GBK
puts a + b
#=> Encoding::CompatibilityError: incompatible character encodings: UTF-8 and GBK
于 2013-03-27T19:19:01.250 回答