YAML 1.2是(关于重复键的一个小警告)JSON的超集,因此任何有效的JSON文件也是有效的YAML文件.但是,YAML 1.1规范(具有最多库支持)并未提及JSON.大多数有效的JSON文件都是有效的YAML 1.1文件,但我通过试验PyYaml和Python的标准JSON库发现了至少一个异常:
12345e999被解释为PyYAML字符串和IEEE无穷大的Python的JSON库.有没有人有一个完整的差异列表,比在特定实现中测试边缘情况更有力地确定?(也就是说,从规范的比较中?)例如,我想生成JSON字符串,它们将由JSON解析器和YAML 1.1解析器以相同的方式解释:我必须在字符串上放置哪些约束?
见这里(特别是脚注25).它说:
不兼容性如下:JSON允许扩展字符集,如UTF-32,并且相对于YAML具有不兼容的unicode字符转义语法; YAML在逗号,等号和冒号之后的分隔符之间需要一个空格,而JSON则不需要.一些非标准的JSON实现扩展了语法,包括Javascript的/*...*/ comments.在解析为内联YAML之前,处理此类边缘情况可能需要对JSON进行轻度预处理
另请参见https://metacpan.org/pod/JSON::XS#JSON-and-YAML
正如您所注意到的,一方面是规范所说的另一方面是常用的解析器(YAML和JSON)处理的内容。因此,您应该考虑多个方面并使用最小公分母,以免无法使用 YAML 解析器加载您的 JSON。
在 JSON 方面有多种标准和最佳实践。最初,JSON 文本必须在最顶层有一个对象或数组。根据json.org站点fail1.json上的可用文件,情况仍然如此:
"A JSON payload should be an object or array, not a string."
Run Code Online (Sandbox Code Playgroud)
根据RFC7159,任何值都可以在顶层(除了使用字符串,这会导致 JSON 文件相当无聊):
JSON 文本是一个序列化值。请注意,某些先前的 JSON 规范将 JSON 文本限制为对象或数组。仅生成需要 JSON 文本的对象或数组的实现将是可互操作的,因为所有实现都将接受这些作为一致的 JSON 文本。
由于 JSON 劫持的问题 * 通过重新定义旧浏览器中的数组处理),有一些实现只接受顶级对象(即文件的第一个字符必须是{.
在 YAML 方面,竞争标准比 JSON 少,但是 YAML 1.1 的持续使用使事情变得混乱,并且如果您在 google 上搜索“yaml current spec”,第一个命中是 yaml.org/ spec/current.html 这实际上是YAML 1.1的旧工作草案
除了 UTF-32 支持提到的其他答案,这在几乎完全使用 UTF-8 的世界中基本上不是问题,还有一些事情需要考虑,特别是如果您希望 PyYAML 能够解析你的 JSON(在 YAML 1.2 规范发布将近八年后,PyYAML 仍然只实现了 YAML 1.1 的大部分内容):
JSON 中的数字在尾数中不需要点,即使这样的数字有指数:
但是YAML™ 1.1 版的Floating-Point Language-Independent Type确实需要那个点:
|[-]?0\.([0-9]*[1-9])?e[-+](0|[1-9][0-9]+) (scientific)
^--- no ? or * associated with this dot
Run Code Online (Sandbox Code Playgroud)
(在 YAML 1.2 规范中,此正则表达式已更改为:
-? [1-9] ( \. [0-9]* [1-9] )? ( e [-+] [1-9] [0-9]* )?.
Run Code Online (Sandbox Code Playgroud)
即使有e(并且没有E)和指数,也允许点消失。
这就是12345e999JSON(溢出)和 PyYAML(字符串)对您的处理方式不同的原因。在 YAML 1.1 中,这只能解释为字符串,因此不需要引号,可以是纯标量。
在 YAML 1.1 中有转义序列,但这不是 JSON 支持的超集。正斜杠 ( /) 可以在 JSON 中转义,但不能在YAML 1.1 中转义(它可以在YAML 1.2 中,规则 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) 解析器都适用。
¹在ruamel.yaml中,我是其作者的 YAML 1.2 解析器,\/正确处理了不带点的科学数字:您的12345e999加载为类型float并打印为inf.
| 归档时间: |
|
| 查看次数: |
2370 次 |
| 最近记录: |