我有一个像这样的ruby哈希:
myhash = { title: 'http://google.com'}
我试图将此添加到yaml文件中,如下所示:
params['myhash'] = myhash
File.open('config.yaml', 'w') do |k|
k.write params.to_yaml
end
问题在于YAML正在删除链接周围的引号,即使它们是必需的(它们包含':')。
根据Stackoverflow上的几个问题,YAML应该只在不需要时删除引号。
我找到了一个Solution,但它确实很难看,如果有其他解决方案,我宁愿不使用它。
我认为在这种情况下,yaml应该包含引号。有什么理由不这样做吗?
注意:链接是动态创建的
答案 0 :(得分:1)
您的示例字符串不需要引号。来自the specs:
通常,YAML坚持使用空格将“:”映射值指示符与值分开。这种限制的好处是“:”字符可以在普通标量中使用,只要它后面没有空格。
例如:
h = { value1: 'quotes: needed', value2: 'quotes:not needed' }
puts h.to_yaml
结果:
---
:value1: 'quotes: needed'
:value2: quotes:not needed
答案 1 :(得分:1)
几个小时之后,我发现它在python中更容易。
用法:python quotes.py *.yml
使用ruamel替换yaml lib,yaml lib似乎无法处理某些UTF-8条目
from ruamel import yaml
import io
import sys
class quote_or_literal(unicode):
pass
def str_presenter(dumper, data):
if data.count("\n"): # check for multiline string
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
else:
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')
yaml.add_representer(quote_or_literal, str_presenter)
def quote_dict(d):
new = {}
for k, v in d.items():
if isinstance(v, dict):
v = quote_dict(v)
else:
v = quote_or_literal(v)
new[k] = v
return new
def ensure_quotes(path):
with io.open(path, 'r', encoding='utf-8') as stream:
a = yaml.load(stream, Loader=yaml.Loader)
a = quote_dict(a)
with io.open(path, 'w', encoding='utf-8') as stream:
yaml.dump(a, stream, allow_unicode=True,
width=1000, explicit_start=True)
if __name__ == "__main__":
for path in sys.argv[1:]:
ensure_quotes(path)