哪些有效的JSON文件不是有效的YAML 1.1文件?
YAML 1.2(其中一个关于重复键)是JSON的超集,因此任何有效的JSON文件也是有效的YAML文件。但是,这个(包含最多的)没有提到JSON。大多数有效的JSON文件都是有效的YAML 1.1文件,但我通过试验PyYaml和Python的标准JSON库发现了至少一个例外:哪些有效的JSON文件不是有效的YAML 1.1文件?,json,yaml,Json,Yaml,YAML 1.2(其中一个关于重复键)是JSON的超集,因此任何有效的JSON文件也是有效的YAML文件。但是,这个(包含最多的)没有提到JSON。大多数有效的JSON文件都是有效的YAML 1.1文件,但我通过试验PyYaml和Python的标准JSON库发现了至少一个例外: PyYAML和Python的JSON库将双精度浮点溢出(如12345e999)解释为字符串 是否有人有一个完整的差异列表,比在特定实现中测试边缘案例更可靠地确定?(也就是说,通过对规范的比较?)例如,我想生成JSON
- PyYAML和Python的JSON库将双精度浮点溢出(如
)解释为字符串12345e999
正如您所注意到的,一件事是规范说明的内容,另一件事是常见的解析器(YAML和JSON)处理的内容。因此,您应该考虑几个方面,并使用最小公分母来避免使用YAML解析器加载JSON 在JSON方面,有多种标准和最佳实践。最初,JSON文本必须在最顶层有一个对象或数组。根据网站上可用的
fail1.json
文件,情况仍然如此:
根据定义,任何值都可以位于顶层(除了使用字符串之外,这会导致相当无聊的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中的数字尾数不需要点,即使这样的数字有指数:
但是,这确实需要点:
(在YAML 1.2规范中,此正则表达式已更改为:|[-]?0\.([0-9]*[1-9])?e[-+](0|[1-9][0-9]+) (scientific) ^--- no ? or * associated with this dot
允许点消失,即使存在-? [1-9] ( \. [0-9]* [1-9] )? ( e [-+] [1-9] [0-9]* )?.
(且没有e
)和指数 这就是您的e
被JSON(溢出)和PyYAML(字符串)以不同方式处理的原因。在YAML 1.1中,这只能解释为字符串,因此不需要引号,可以是纯标量12345e999
- YAML 1.1中有转义序列,但这不是JSON支持的超集。正斜杠(
)可以在JSON中转义,但不能在(规则53中可以转义)/
- 在JSON和YAML 1.1中,您可以使用
来表示16位unicode代码点。尽管YAML 1.1规范(和YAML 1.2)提到代理项对与使用UTF-16结合使用,但没有提到此类对作为转义序列(\unnn
)。RFC 7159中明确提到此字符串序列表示G谱号字符(U+1D11E)。我不知道有任何YAML解析器支持此,PyYAML抛出: yaml.reader.ReaderError:不可接受字符#xd834:不允许使用特殊字符“\uD834\uDD1E”
- 作为UTF-8
- 顶层是一个对象
- 科学数字总是带点的
- 无转义序列
- 在
和\uD7FF
(独占)之间没有\uE000
字符,也没有\unnn
,也没有\uFFFE
\uFFFF
在我是作者的YAML 1.2解析器中,
\/
和不带点的科学数字被正确处理:您的12345e999
加载为typefloat
并打印为inf
我说,“有人有列表吗…”。我不是要求人们做新的工作,我是问以前是否有人遇到过这个问题,以便我们可以共享结果。我不认为12345e999
示例表明该文件不是有效的JSON或YAML。1)这两个实现对它的解释都没有错误(当然,这可能是错误的);2)AFAIK YAML和JSON规范都没有严格定义实现必须支持的浮点值的范围,因此实现特定的行为是公平的
-? [1-9] ( \. [0-9]* [1-9] )? ( e [-+] [1-9] [0-9]* )?.