使用PyYAML将文档加载为原始字符串
我想解析像下面这样的yaml文档:
meta-info-1: val1
meta-info-2: val2
---
Plain text/markdown content!
jhaha
如果我用PyYAML的load_all
来加载这个文档,我会得到以下结果:
>>> list(yaml.load_all(open('index.yml')))
[{'meta-info-1': 'val1', 'meta-info-2': 'val2'}, 'Plain text/markdown content! jhaha']
我想要实现的目标是,这个yaml文件应该包含两个文档,而第二个文档应该被当作一个完整的字符串来理解,更具体地说,就是任何带有markdown格式的大段文本。我不想让它被解析成YAML语法。
在上面的例子中,PyYAML把第二个文档返回为一个完整的字符串。但是如果第二个文档里有一个:
字符代替!
,我就会遇到语法错误。这是因为PyYAML正在解析那个文档里的内容。
有没有办法告诉PyYAML,第二个文档只是一个原始字符串,不要去解析它呢?
编辑:这里有一些很好的回答。虽然使用引号或字面量语法解决了这个问题,但我希望用户能够写出纯文本,而不需要额外的格式。只需要三个-
(或者.
)就可以写出一大段纯文本,可能还包括引号。所以,我想知道是否可以告诉PyYAML只解析一个文档,把第二个文档原样给我。
编辑 2:借鉴agf的想法,考虑到第二个文档可能是有效的yaml语法,而不是使用try/except来处理,
config_content, body_content = open(filename).read().split('\n---')
config = yaml.loads(config_content)
body = yaml.loads(body_content)
谢谢agf。
2 个回答
2
如果你只是想在YAML中处理冒号这个字符,可以把它放在单引号或双引号里面。另外,你也可以试试字面量风格,这样你的第二个文档就可以当作一个整体来处理。
6
你可以这样做:
raw = open(filename).read()
docs = []
for raw_doc in raw.split('\n---'):
try:
docs.append(yaml.load(raw_doc))
except SyntaxError:
docs.append(raw_doc)
如果你无法控制原始文档的格式。
根据PyYAML的文档:
双引号是最强大的格式,也是唯一可以表示任何标量值的格式。使用双引号的标量可以进行转义。通过使用转义序列 \x** 和 \u****,你可以表示任何ASCII或Unicode字符。
所以听起来,如果不是用双引号包起来,就无法在解析时表示任意的标量值。