2016-07-05 170 views
2

我有一個YAML文件,並希望限制某個字段不包含空格。爲什麼PyYAML和ruamel.yaml在單引號時會轉義特殊字符?

以下是一個演示我嘗試的腳本:

test.py

#!/usr/bin/env python3 

import os 
from ruamel import yaml 

def read_conf(path_to_config): 
    if os.path.exists(path_to_config): 
     conf = open(path_to_config).read() 
     return yaml.load(conf) 
    return None 

if __name__ == "__main__": 
    settings = read_conf("hello.yaml") 
    print("type of name: {0}, repr of name: {1}".format(type(
      settings['foo']['name']), repr(settings['foo']['name']))) 
    if any(c.isspace() for c in settings['foo']['name']): 
     raise Exception("No whitespace allowed in name!") 

這裏是我的YAML文件的第一刀:

hello.yaml

foo: 
    name: "hello\t" 

在上述YAML文件,一個例外是正確提出:

type of name: <class 'str'>, repr of name: 'hello\t' 
Traceback (most recent call last): 
    File "./test.py", line 16, in <module> 
    raise Exception("No whitespace allowed in name!") 
Exception: No whitespace allowed in name! 

但是,如果我改變了雙引號爲單引號,則不會引發異常:

08:23 $ ./test.py 
type of name: <class 'str'>, repr of name: 'hello\\t' 

此行爲在使用ruamel.yaml==0.11.11PyYAML=3.11時都會發生。

爲什麼這些Python YAML解析器中的單引號和雙引號之間有區別,據我所知,它們在YAML規範中沒有功能差異?我如何防止特殊字符被轉義?

+1

什麼'yaml'模塊是Python3原生的? 'ruamel.yaml'和'PyYAML'都不是標準python庫的一部分。 – Anthon

+0

@Anthon哎呀。我在全球安裝了PyYAML,但沒有意識到它。 :)將編輯。 – erip

回答

3

單引號和雙引號字符串之間的YAML規範有很大差異。在single quoted scalars內,您只能避開單引號:

單引號樣式由周圍的「'」指示符指定。因此,在單引號標量中,需要重複這些字符。這是用單引號標量執行的唯一轉義形式。

因此\'hello\t'沒有特殊的功能和標量由字母hel(2次),o的。 \t

僅在雙引號的YAML標量中支持反斜槓轉義。

+1

啊,我的理解是越野車。 :)我想我需要擴大我的約束,以防止所有特殊字符。 – erip

+1

您可以在單引號(以及文字和摺疊塊標量)中使用製表符,但必須使用製表符本身,而不是通常的轉義序列('\ t')。那些角色在很多情況下很難與空間區分開來,但這是正確的YAML – Anthon