在yaml中强制引用

时间:2017-09-09 11:44:51

标签: ruby hyperlink yaml

我有一个像这样的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应该包含引号。有什么理由不这样做吗?

注意:链接是动态创建的

2 个答案:

答案 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

  • 如果字符串包含' \ n'。
  • ,则此脚本使用文字格式
  • 使用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)