Yaml将字符串加载到UTF8?

时间:2016-11-28 14:48:55

标签: python character-encoding yaml

我有这个YAML:

---
test: {"gender":0,"nacionality":"Alem\u00e3o"}

我正在使用python 3.5阅读它,如下所示:

with open('teste.yaml', 'r') as stream:
    doc = yaml.load_all(stream)
    for line in doc:
        print(line)

这是我得到的结果:

{'test': {'gender': 0, 'nacionality': 'Alemão'}}

但如果我在YAML中更改"的{​​{1}},我就明白了:

'

正如您所看到的,当我使用{'test': {'nacionality': 'Alem\\u00e3o', 'gender': 0}} 时,字符串"将转换为UTF,但Alem\\u00e3o则不会转换为UTF。

所以我有两个问题:

当我使用''时,为什么会得到不同的输出? 使用"时,如何才能将输出设为Alem\\u00e3o

2 个答案:

答案 0 :(得分:1)

这是如何定义YAML数据格式的。在双引号内,解释特定的转义序列。在单引号内,它们不是。

  

7.3.1。双引号样式

     

双引号样式由周围的“"”指示符指定。这是唯一能够通过使用“\”转义序列表达任意字符串的样式。这是以逃避“\”和“"”字符为代价的。

     

http://yaml.org/spec/1.2/spec.html#id2787109

  

使用&#34时,如何将输出设为Alem \ u00e3?

逃离逃脱角色:

test: {"gender":0,"nacionality":"Alem\\u00e3o"}

答案 1 :(得分:1)

YAML中的反斜杠转义仅适用于双引号标量。不是单引号标量,非引用标量或(文字)标量标量。

要获得所需的输出,最好的方法是将引号全部放在一起并将其用作输入:

---
test: {gender: 0, nacionality: Alem\u00e3o}

然而,您的计划有所改善。

  1. 您不应该对此类未标记的YAML使用load_all()load()。这是不安全的,如果您无法完全控制源YAML,则可能导致在您的计算机上执行任意代码。如果您没有明确指定不安全的Loader作为参数,则较新版本的ruamel.yaml将发出警告。帮自己一个忙,养成使用safe_load()safe_load_all()
  2. 的习惯
  3. load_all()返回文档的迭代器,因此使用docline是误导性的变量名。你应该使用:

    import ruamel.yaml as yaml
    
    with open('teste.yaml', 'r') as stream:
        for doc in yaml.safe_load_all(stream):
            print(doc)
    

    或如果teste.yaml中只有一个文档,您可以将其简化为:

    import ruamel.yaml as yaml
    
    with open('teste.yaml') as stream:
        print(yaml.safe_load(stream))
    

    这两个都会给你:

    {'test': {'gender': 0, 'nacionality': 'Alem\\u00e3o'}}
    
  4. 请注意,YAML中必须在:分隔键和映射值之后留出空格。只有与JSON兼容才允许在假设引用键的情况下删除空间(双引号和单引号都有效)。所以这也是输入:

    ---
    test: {"gender":0, 'nacionality':Alem\u00e3o}