是否需要使用引号取决于解析器。据我所知,Docker-compose仍然依赖于PyYAML模块,它实现了大部分YAML 1.1,并有一些自己的怪癖。
通常,只有在字符串可能被误解或与某些不是标量字符串的YAML构造相冲突时才需要用引号引起来。您还需要(双重)引号来表示不能用普通标量、单引号标量或块样式文字或折叠标量表示的内容。
误解
您需要引用看起来像其他数据结构的字符串:
- 布尔值:"True","False",但是PyYAML还假定替代词"是","否","打开","关闭"表示布尔值(所有小写字母和大写字母版本也应考虑)。请注意,YAML 1.2标准删除了对这些替代方案的引用。
- 整数:包括仅由数字组成的字符串。但还包括十六进制(
0x123
)和八进制数字(
0123
)。在YAML 1.2中,八进制数以
0o123
形式编写,但是PyYAML不支持此功能,因此最好引用两者。
- 特殊整数PyYAML仍然支持,但在YAML 1.2规范中也不支持,即:基于60的数字,由冒号(
:
)分隔,时间指示以及如果冒号之间/之后的值在00-59范围内,则也可以将MAC地址解释为这样的数字。
- 浮点数:如
1E3
(带有可选符号和尾数的字符串)应该用引号引起来。当然,如果3.14是一个字符串,那么它也需要加引号。并且带有尾数的60进制浮点数(在最终冒号后面的数字后面带有尾数)也应该加引号。
- 时间戳:
2001-12-15T02:59:43.1Z
,但也应该引用类似iso-8601的字符串,以防止它们被解释为时间戳。
- "null"值写为空字符串,或者
~
或
null
(所有大小写类型都适用),因此与这些匹配的任何字符串都需要加引号。
上述引用可以使用单引号或双引号进行,也可以使用块样式文字或折叠标量。请注意,对于块样式,应使用
|-
resp。
>-
,以不引入原始字符串中没有的尾随换行符。
冲突
YAML为某些字符或字符组合分配了特殊含义。其中一些仅在字符串开头具有特殊含义,而另一些仅在字符串内部具有特殊含义。
- 来自集合
!&*?{[
的字符通常表示特殊的YAML构造。其中一些可能取决于后面的字符而消除歧义,但我不会依赖这个。
- 紧接着
#
的空格表示行末注释
- 无论在哪里都可以使用键(在块模式下,在许多位置)冒号 + 空格组合(
:
)表示将要跟随一个值。如果该组合是您标量字符串的一部分,则必须引用它。
与误解一样,您可以使用单引号或双引号或块状文本或折叠标量。块状标量的第一行之外不能有行末注释。
PyYAML还会混淆纯量标量中的任何冒号+空格(即使这是在值中),因此请始终引用这些内容。
表示特殊字符
您可以在YAML文件中插入特殊字符或Unicode代码点,但是如果您想在所有情况下清晰地看到这些字符,您可能需要使用转义序列。在这种情况下,您必须使用双引号,这是唯一允许反斜杠转义的模式。例如:\u2029
。此类转义的完整列表可以从标准中获取,但请注意,PyYAML没有实现例如\/
(或者至少在我分叉该库时没有)。
找出何时需要引用或不引用的一个技巧是使用用于转储字符串的库。当潜在地转储纯量标量时,我的ruamel.yaml
和由docker-compose使用的PyYAML都尝试读回字符串的纯量表示形式,如果结果与字符串不同,则需要应用引号。您也可以这样做:如果有疑问,请编写一个小程序,使用PyYAML的safe_dump()
转储您拥有的字符串列表,并在PyYAML适用引号的任何位置应用引号。