将Ruby转换为YAML UTF8字符串

3
如何使ruby的to_yaml方法存储UTF8字符串,但不是转义序列?
4个回答

7
require 'yaml'
YAML::ENGINE.yamler='psych'
'Résumé'.to_yaml # => "--- Résumé\n...\n"

Ruby内置了两个YAML引擎:syck和psych。Syck已经过时且未得到维护,但是在1.9.2中是默认的,因此需要切换到psych。Psych将UTF-8字符串转储为UTF-8。


1
请注意,此答案仅适用于Ruby 1.9.3(其中Psych已成为默认设置)。上述代码无法在Ruby 1.9.2中运行(“没有这样的文件或目录 - psych”)。 - Phrogz
1
除非您首先安装 psych gem。 - Phrogz

3

我想这可能不是一个好主意,因为我相信YAML对字符进行编码有其原因,但是它似乎并不太难撤消:

require 'yaml'
require 'yaml/encoding'

text = "Ça va bien?"

puts text.to_yaml(:Encoding => :Utf8) # => --- "\xC3\x87a va bien?"
puts YAML.unescape(YAML.dump(text)) # => --- "Ça va bien?"

过去默认使用ASCII编码是合理的,但现在不再是这样。而且手册上说:“YAML流使用一组可打印的Unicode字符进行编码,可以使用UTF-8或UTF-16。”。所以我认为这只是Ruby库中的一个限制,to_yaml应该默认返回UTF-8。否则,使用编辑器修改这些YAML文件会非常繁琐。 - tokland
1
有时候,dump函数会返回一个二进制类型:YAML.unescape(YAML.dump("sú")) -> --- !binary | c8O6 - tokland

3

1
你可以在这里找到带有gemspec的更新版本:https://github.com/afunai/ya2yaml - makevoid

2
对于Ruby 1.9.3+,这不是一个问题:默认的YAML引擎是Psych,它默认支持UTF-8。
对于Ruby 1.9.2及以下版本,您需要安装psych gem并在需要yaml之前require它:
irb(main):001:0> require 'yaml'
#=> true
irb(main):002:0> require 'psych'
#=> true
irb(main):003:0> YAML::ENGINE
#=> #<YAML::EngineManager:0x00000001a1f642 @yamler="syck">
irb(main):004:0> "ça va?".to_yaml
#=> "--- \"\\xC3\\xA7a va?\"\n"

irb(main):001:0> require 'psych' # gem install psych
#=> true
irb(main):002:0> require 'yaml'
#=> true
irb(main):003:0> YAML::ENGINE
#=> #<YAML::EngineManager:0x00000001a1f828 @yamler="psych">
irb(main):004:0> "ça va bien!".to_yaml
#=> "--- ça va bien!\n...\n"

或者,按照 Evgeny 的建议设置 yamler (假设你已安装了 psych gem):

irb(main):001:0> require 'yaml'
#=> true
irb(main):002:0> YAML::ENGINE.yamler
#=> "syck"
irb(main):003:0> "ça va?".to_yaml
#=> "--- \"\\xC3\\xA7a va?\"\n"
irb(main):004:0> YAML::ENGINE.yamler = 'psych'
#=> "psych"
irb(main):005:0> "ça va".to_yaml
#=> "--- ça va\n...\n"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接