YAML 1.2(对于重复键有一个minor caveat)是JSON的超集,因此任何有效的JSON文件也是有效的YAML文件。但是,YAML 1.1 specification(library support}最多)没有提到JSON。大多数有效的JSON文件都是有效的YAML 1.1文件,但我通过试验PyYaml和Python的标准JSON库发现了至少一个例外:
12345e999
等双精度浮点溢出解释为PyYAML和IEEE infinity的字符串。是否有人有完整的差异列表,比通过测试特定实现中的边缘案例更有力地确定? (也就是说,从规范的比较?)例如,我想生成JSON字符串,它们将由JSON解析器和YAML 1.1解析器以相同的方式解释:我必须在字符串上放置哪些约束?
答案 0 :(得分:8)
见here(特别是脚注25)。它说:
不兼容性如下:JSON允许扩展字符 像UTF-32一样设置并且具有不兼容的unicode字符转义语法 相对于YAML; YAML在逗号之类的分隔符之后需要一个空格, 等于,而冒号虽然JSON没有。有些不规范 JSON的实现扩展了语法以包含Javascript /*...*/ 评论。处理这种边缘情况可能需要光线 在解析为内联YAML之前预处理JSON
另见https://metacpan.org/pod/JSON::XS#JSON-and-YAML
相关强>
What is the difference between YAML and JSON? When to prefer one over the other
答案 1 :(得分:2)
正如您所注意到的,有一件事是规范说明了其他常用解析器(YAML 和 JSON)处理的内容。因此,您应该考虑几个方面,并使用最小公分母,以便无法使用YAML解析器加载JSON。
在JSON方面,有多种标准和最佳实践。最初,JSON文本必须在最顶层有一个对象或数组。根据{{3}}网站上提供的fail1.json
文件,仍然如此:
"A JSON payload should be an object or array, not a string."
根据json.org,任何值都可以在顶层(除了使用字符串,这会导致相当无聊的JSON文件):
JSON文本是序列化值。注意某些先前的 JSON的规范将JSON文本约束为对象或 阵列。仅生成对象或数组的实现 调用的JSON文本在所有方面都是可互操作的 实现将接受这些作为符合JSON文本。
由于JSON劫持问题(通过重新定义旧浏览器中的数组),已经存在只接受顶层对象的实现(即文件的第一个字符必须是{
。
在YAML方面,与JSON相比,竞争标准较少,但YAML 1.1的持续使用使得事情变得混乱,并且如果你谷歌获得“yaml current spec”,那么第一次打击就是yaml .org / spec / current.html,这实际上是YAML 1.1 的工作草案
除了UTF-32支持之外,提到的另一个答案,在一个几乎完全使用UTF-8的世界中基本上没有问题,有一些事情需要考虑,特别是如果你想让PyYAML成为能够解析你的JSON(PyYAML仍然只实现了大部分的YAML 1.1,接近YAML 1.2规范发布后的八年):
JSON中的数字在尾数中不需要一个点,即使这样的数字有一个指数:
|[-]?0\.([0-9]*[1-9])?e[-+](0|[1-9][0-9]+) (scientific)
^--- no ? or * associated with this dot
(在YAML 1.2规范中,此正则表达式已更改为:
-? [1-9] ( \. [0-9]* [1-9] )? ( e [-+] [1-9] [0-9]* )?.
即使有e
(并且没有E
)和指数,也允许点消失。
这是12345e999
被JSON(溢出)和PyYAML(字符串)处理的原因。在YAML 1.1中,这只能被解释为一个字符串,因此不会需要引号并且可以是普通标量。
在YAML 1.1中有转义序列,但这不是JSON支持的超集。正斜杠(/
)可以在JSON中转义,但不能在Floating-Point Language-Independent Type for YAML™ Version 1.1中转义(它可以在YAML 1.1,规则53中)
在JSON和YAML 1.1中,您可以使用\uNNNN
来指示16位的unicode代码点。虽然YAML 1.1规范(和YAML 1.2)在使用UTF-16时提到了代理对,但没有提到关于这些对作为转义序列("\uD834\uDD1E"
)。此字符串序列在RFC 7159中明确提及为表示G谱号字符(U + 1D11E)。我不知道任何支持它的YAML解析器,PyYAML会抛出:
yaml.reader.ReaderError:不可接受的字符#xd834:不允许使用特殊字符
只要你写下你的JSON
\/
转义序列\uNNNN
和\uD7FF
之间没有\uE000
个字符(不包括),\uFFFE
也不\uFFFF
你应该对JSON和YAML(1.1)解析器都没问题。
¹在YAML 1.2我作为作者的YAML 1.2解析器中,正确处理\/
和没有点的科学数字:12345e999
加载为float
类型{{ 1}}并打印为inf
。