9

以下...

require 'yaml'
test = "I'm a b&d string"
File.open('test.yaml', 'w') do |out|
  out.write(test.to_yaml)
end

...输出...

--- this is a b&d string

我怎样才能让它输出

--- 'this is a b&d string'

???

4

2 回答 2

18

如果您想在 YAML 中存储转义字符串,#inspect请在将其转换为 YAML 之前使用它进行转义:

irb> require 'yaml'
=> true
irb> str = %{This string's a little complicated, but it "does the job" (man, I hate scare quotes)}
=> "This string's a little complicated, but it \"does the job\" (man, I hate scare quotes)"
irb> puts str
This string's a little complicated, but it "does the job" (man, I hate scare quotes)
=> nil
irb> puts str.inspect
"This string's a little complicated, but it \"does the job\" (man, I hate scare quotes)"
=> nil
irb> puts str.to_yaml
--- This string's a little complicated, but it "does the job" (man, I hate scare quotes)
=> nil
irb> puts str.inspect.to_yaml
--- "\"This string's a little complicated, but it \\\"does the job\\\" (man, I hate scare quotes)\""
=> nil

除非必须,否则 YAML 不会引用字符串。如果字符串包含不带引号存储它会丢失的内容,它会引用字符串 - 例如周围的引号字符或尾随或前导空格:

irb> puts (str + " ").to_yaml
--- "This string's a little complicated, but it \"does the job\" (man, I hate scare quotes) "
=> nil
irb> puts %{"#{str}"}.to_yaml
--- "\"This string's a little complicated, but it \"does the job\" (man, I hate scare quotes)\""
=> nil
irb> puts (" " + str).to_yaml
--- " This string's a little complicated, but it \"does the job\" (man, I hate scare quotes)"
=> nil

但是,作为 YAML 使用者,字符串是否被引用对您来说并不重要。您永远不应该自己解析 YAML 文本 - 将其留给库。如果您需要在 YAML 文件中引用字符串,那对我来说很糟糕。

无论您的字符串中是否包含 '&',YAML 都会保留该字符串:

irb> test = "I'm a b&d string"
=> "I'm a b&d string"
irb> YAML::load(YAML::dump(test))
=> "I'm a b&d string"
irb> YAML::load(YAML::dump(test)) == test
=> true
于 2009-04-03T21:52:23.057 回答
5

根据YAML 1.2 规范,JSON 文档是有效的 YAML 文档。

此修订的主要目标是使 YAML 作为官方子集与 JSON 兼容。

因此,有效的 JSON 字符串就是有效的 YAML 字符串。

require 'json'
'my string'.to_json  # => produces a valid YAML string

这对于富含 ERB 语法的 YAML 文件非常有用,string.to_yaml在许多情况下这些文件将不起作用。

例子:

# openvpn.yml.erb
openvpn:
  cert: <%= ENV.fetch('OPENVPN_CERT').to_json %>
  key: <%= ENV.fetch('OPENVPN_KEY').to_json %>
于 2017-12-18T17:21:26.963 回答