我在使用UTF-8格式的字符串时遇到问题,例如“\ u0161 \ u010D \ u0159 \ u017E \ u00FD”。 当这样的字符串在我的程序中定义为变量时,它可以正常工作。但是当我通过从一些外部文件中读取它来使用这样的字符串时,我得到错误的输出(我没有得到我想要/期望的东西)。我肯定错过了一些必要的编码......
我的代码:
file = "c:\\...\\vlmList_unicode.txt" #\u306b\u3064\u3044\u3066
data = File.open(file, 'rb') { |io| io.read.split(/\t/) }
puts data
data_var = "\u306b\u3064\u3044\u3066"
puts data_var
输出:
\u306b\u3064\u3044\u3066 # what I don't want
について # what I want
我试图通过指定'rb'来读取二进制形式的文件,但显然还有其他一些问题...... 我使用JRuby 1.7.3中的构建在Netbeans 7.3.1中运行我的代码(我也尝试过Ruby 2.0.0但没有任何影响。)
因为我是红宝石世界的新人,所以欢迎任何想法......
答案 0 :(得分:1)
如果您的文件包含文字转义字符串:
\u306b\u3064\u3044\u3066
然后你需要在阅读后解开它。 Ruby使用字符串文字为您完成此操作,这就是为什么第二种情况适合您。取自“Is this the best way to unescape unicode escape sequences in Ruby?”的答案,您可以使用:
file = "c:\\...\\vlmList_unicode.txt" #\u306b\u3064\u3044\u3066
data = File.open(file, 'rb') { |io|
contents = io.read.gsub(/\\u([\da-fA-F]{4})/) { |m|
[$1].pack("H*").unpack("n*").pack("U*")
}
contents.split(/\t/)
}
或者,如果您希望使其更具可读性,请将替换提取到新方法中,然后将其添加到String
类:
class String
def unescape_unicode
self.gsub(/\\u([\da-fA-F]{4})/) { |m|
[$1].pack("H*").unpack("n*").pack("U*")
}
end
end
然后你可以打电话:
file = "c:\\...\\vlmList_unicode.txt" #\u306b\u3064\u3044\u3066
data = File.open(file, 'rb') { |io|
io.read.unescape_unicode.split(/\t/)
}
答案 1 :(得分:0)
就像一个FYI:
data = File.open(file, 'rb') { |io| io.read.split(/\t/) }
可以更简单地写成以下之一:
data = File.read(file, 'rb').split(/\t/)
data = File.readlines(file, "\t", 'mode' => 'rb')
(请记住,File继承自IO,这是定义这些方法的地方,因此请查看IO以获取有关它们的文档。)
readlines
采用“separator”参数,在上面的示例中为“\ t”。 Ruby会将它替换为* nix或Mac OS上的常用“\ n”或Windows上的“\ r \ n”,因此将使用制表符分隔符检索记录。
这让我想知道为什么你想要这样做呢?我从来没有看到制表符作为记录分隔符,只有“TSV”(Tab-Seperated-Value)文件中的列/字段分隔符。所以这让我觉得你应该使用Ruby的CSV类,并使用“\ t”作为列分隔符。但是,如果没有您正在阅读的实际文件的样本,我无法肯定地说。