我的Ruby代码中有一个UTF-8字符串。由于限制,我想将该字符串中的UTF-8字符转换为它们的转义等效项(例如\u23
),或者将整个字符串转换为UCS-2。我需要明确地执行此操作以将数据导出到文件中
我尝试在IRB中执行以下操作:
my_string = '7.0mΩ'
my_string.encoding
my_string.encode!(Encode::UCS_2BE)
my_string.encoding
其输出是:
=> "7.0mΩ"
=> #<Encoding::UTF-8>
=> "7.0m\u2126"
=> #<Encoding::UTF-16BE>
在我从数组中读取数据(在Rails中)之前,这似乎工作正常(我得到2126的“ ohm”):
data.each_with_index do |entry, idx|
puts "#{idx} !! #{entry['title']} !! #{entry['value']} !! #{entry['value'].encode!(Encoding::UCS_2BE)}"
end
这会导致错误:
不兼容的字符编码:UTF-8和UTF-16BE
然后我尝试编写一个基本的文件转换例程:
File.open(target, 'w', encoding: Encoding::UCS_2BE) do |file|
File.open(source, 'r', encoding: Encoding::UTF_8).each_line do |line|
output.puts(line)
end
end
这导致文件中出现各种奇怪的字符。
不知道出了什么问题。
是否有更好的方法来解决在Ruby中将UTF-8数据转换为UCS-2的问题?我真的不介意在字符串中将其实际更改为\u2126
而不是实际值。
帮助!
我用猴子修补了它以做我想要的。它不是很优雅,但是可以完成工作(是的,我知道这还不是很漂亮。。。只是为了获得我需要的东西而已):
def hacky_encode
encoded = self
unless encoded.ascii_only?
encoded = scan(/./).map do |char|
char.ascii_only? ? char : char.unpack('U*').map { |i| '\\u' + i.to_s(16).rjust(4, '0') }
end.join
end
encoed
end
可以使用:
"7.0mΩ".hacky_encode