我在解析使用两个空格缩进创建的 YAML(使用 Ruby 2.5/Psych(时看到了奇怪的行为。同一个文件,缩进每行四个空格 - 在我看来 - 正如预期的那样。
两个空格:
windows:
- shell:
panes:
- echo hello
结果为以下哈希:
{"windows"=>[{"shell"=>nil, "panes"=>["echo hello"]}]}
而使用四个空格缩进:
windows:
- shell:
panes:
- echo hello
结果在:
{"windows"=>[{"shell"=>{"panes"=>["echo hello"]}}]}
我只是浏览了规范,没有看到与此问题相关的任何内容。
这种行为是预期的吗?如果是这样,我将非常感谢解释原因的资源链接。
虽然韦恩的解决方案是正确的,但解释似乎有点不对劲,所以我会抛出我的:
在 YAML 中,块序列项(如块映射的?
和:
(的-
被视为缩进(规范(:
用于表示块集合条目的"-"、"?"和":"字符被人们视为缩进的一部分。这是由相关制作公司根据具体情况处理的。
此外,所有块集合(序列和映射(都从其第一项开始缩进(因为没有明确的起始指示器(。所以在行- shell:
中,-
定义了新开始序列的缩进级别,同时,shell:
定义了新开始的映射的缩进级别,即序列项的内容。请注意如何将-
视为缩进,以定义映射的缩进级别。
现在,重温您的第一个示例:
windows:
- shell:
panes:
- echo hello
panes:
与shell:
处于同一水平。这意味着 YAML 将其解析为由shell:
开始的映射的键,这意味着键shell
具有空值。隐式键的映射值(如果不在同一行上(必须始终缩进到比相应的映射键(规范(多
块节点的属性可能跨越多行。在这种情况下,无论块集合条目的缩进如何,它们都必须比块集合至少多缩进一个空格。
OTOH,在第二个示例中:
windows:
- shell:
panes:
- echo hello
与panes:
相比,shell:
的缩进级别更深。这意味着它被解析为键shell
的值,从而启动一个新的嵌套块映射。
最后,请注意,由于-
被视为缩进的一部分,因此"缩进两个空格">也可能意味着:
windows:
- shell:
panes:
- echo hello
请注意,-
的缩进程度并不比其映射键多。这是有效的,因为规范说:
由于人们将"-"指示器视为缩进,因此嵌套的块序列可能会缩进一个空格来补偿,当然,如果嵌套在另一个块序列中(块出上下文与块输入上下文(。
问题是你不能简单地用四个空格替换每两个空格。 那是因为在这对行中:
- shell:
panes:
第二行中的这两个空格:
panes:
^^
是上面行中"-"的缩写。 如果第二行没有缩写,那么这对行将是:
- shell:
- panes:
因此,当将缩进加倍时,这些行的第二对应该只将其第一对空格加倍,而不是第二对空格。 这将为该对产生正确的缩进:
- shell:
panes:
因此,如果您只展开"窗格:"行中的第一对空格,您将获得:
windows:
- shell:
panes:
- git status
这将正确解析为预期结果。