YAML格式
根据 YAML 官方网站的说法,YAML是“一个对所有编程语言都十分友好的序列化标准”(a human friendly data serialization standard for all programming languages)。
就算YAML能够描述复杂的嵌套数据结构,本文仍然只解释“在使用YAML进行文件配置时”所需要的最小化功能集合。
YAML是个简单的语言,可以描述数据。就像PHP,它有诸如字符串、布尔值、浮点或整型等简单的类型语法。但是不同于PHP,它在数组(顺序型)和哈希(映射型)上面有所不同。
标量 ¶
标量的语法类似于PHP。
字符串 ¶
YAML字符串可以用单引或双引号来打包。某些情况下,它们也可以不加引号:
1 2 3 4 5 | A string in YAML
'A singled-quoted string in YAML'
"A double-quoted string in YAML" |
引号十分有用,当字符串起始或结束于“一或多个空格”的话,因为在进行解析式,未加引号的字符串将被两头清空格(trimmed)。当字符串包括特殊的或保留的字符时,使用引号是必须的。
当使用单引号字符串时,内容中的任何单个 '
必须使用两次以进行转义:
1 | 'A single quote '' inside a single-quoted string' |
字符串中包含以下内容时必须使用引号。虽然你可以使用双引,对于这些字符使用单引更为方便,可以避免被迫使用任何 \
来进行转义:
:
,{
,}
,[
,]
,,
,&
,*
,#
,?
,|
,-
,<
,>
,=
,!
,%
,@
,`
双引号提供了一种用于表达任意字符串的方式,使用 \
来转义字符或排序。例如,当你需要内嵌 \n
或Unicode字符到一个字符串中时,它非常有用:
1 | "A double-quoted string in YAML\n" |
如果字符串包含下列控制字符(control characters),必须使用双引进行转义:
\0
,\x01
,\x02
,\x03
,\x04
,\x05
,\x06
,\a
,\b
,\t
,\n
,\v
,\f
,\r
,\x0e
,\x0f
,\x10
,\x11
,\x12
,\x13
,\x14
,\x15
,\x16
,\x17
,\x18
,\x19
,\x1a
,\e
,\x1c
,\x1d
,\x1e
,\x1f
,\N
,\_
,\L
,\P
最后,还有其他一些场合需要引号,不管你使用双引还是单引:
- 当字符串是
true
或false
(否则,它将被当作布尔值对待); - 当字符串是
null
或~
(否则,它会被认为是null
值); - 当字符串看起来像数字,比如整型 (如
2
,14
, 等等), floats (e.g.2.6
,14.9
) 以及指数数字 (如12e7
, 等等) (否则,它将被当作数字值对待); - 当字符串看起来像日期 (如
2014-12-31
) (否则,它将被自动转换成Unix timestamp)。
当一个字符串包含line break(换行)时,你应该使用literal style,它通过pipe(|
)进行指示,以指明一个字符串将撑开数行。在literal中,新行是被保留的:
1 2 3 | |
\/ /| |\/| |
/ / | | | |__ |
另可选择的是,字符串能够以folded style进行书写,它通过 >
来进行指示,里面的每一个换行将被一个空格替代:
1 2 3 4 5 | >
This is a very long sentence
that spans several lines in the YAML
but which will be rendered as a string
without carriage returns. |
要注意上面例子中的每一行前面的两个空格。它们不会在PHP程序中的结果字符串中出现。
数字 ¶
1 2 | # an integer / 整形
12 |
1 2 | # an octal / 八进制
014 |
1 2 | # an hexadecimal / 十六进制
0xC |
1 2 | # a float / 浮点
13.4 |
1 2 | # an exponential number / 指数数字
1.2e+34 |
1 2 | # infinity / 无限大
.inf |
Nulls ¶
YAML中的null可以被表达为 null
or ~
。
布尔值 ¶
YAML中的布尔值可以被表达为 true
and false
。
日期 ¶
YAML使用ISO-8601标准来表达日期:
1 | 2001-12-14T21:59:43.10-05:00 |
1 2 | # simple date / 简单日期
2002-12-14 |
集合 ¶
一个YAML文件很少只用来描述简单标量。多数时候,它要描述集合(collection)。一个集合,可以包含顺序型或映射型的元素。两种方式皆可转换为PHP数组。
顺序型使用dash(-),其后跟上一个空格:
1 2 3 | - PHP
- Perl
- Python |
这个YAML文件等同于下面的PHP代码:
1 | array('PHP', 'Perl', 'Python'); |
映射型使用冒号加空格(:
)以形成键值对:
1 2 3 | PHP: 5.2
MySQL: 5.1
Apache: 2.2.20 |
等同于以下PHP代码:
1 | array('PHP' => 5.2, 'MySQL' => 5.1, 'Apache' => '2.2.20'); |
在一个映射中,键可以是任何有效的标量。
冒号和值之间的空格数量无关紧要:
1 2 3 | PHP: 5.2
MySQL: 5.1
Apache: 2.2.20 |
在描述嵌套集合时,YAML使用一或多个空格的缩进:
1 2 3 4 5 6 | 'symfony 1.0':
PHP: 5.0
Propel: 1.2
'symfony 1.2':
PHP: 5.2
Propel: 1.3 |
以上YAML文件等同于以下PHP代码:
在YAML文件中使用缩进时,你必须牢记一件重要的事:缩进必须由一或多个空格来完成,但绝对不要使用制表符(tabulators)。
你可以随心所欲地嵌套顺序型和数组型集合:
1 2 3 4 5 6 | 'Chapter 1':
- Introduction
- Event Types
'Chapter 2':
- Introduction
- Helpers |
YAML也可以使用以下风格的集合,使用显式的分隔符而非缩进,来标记其范围。
顺序型集合可以在方括号([]
)中以逗号来分隔列表:
1 | [PHP, Perl, Python] |
映射型集合可以在大括号({}
)中以逗号来分隔键值对:
1 | { PHP: 5.2, MySQL: 5.1, Apache: 2.2.20 } |
你可以混合使用并实现风格匹配,以增强可读性:
1 2 | 'Chapter 1': [Introduction, Event Types]
'Chapter 2': [Introduction, Helpers] |
1 2 | 'symfony 1.0': { PHP: 5.0, Propel: 1.2 }
'symfony 1.2': { PHP: 5.2, Propel: 1.3 } |
注释 ¶
可以通过添加井号(#
)来完成YAML文件中的注释:
1 2 3 4 | # Comment on a line / 整行注释
"symfony 1.0": { PHP: 5.0, Propel: 1.2 } # Comment at the end of a line
# 单行结尾处的注释
"symfony 1.2": { PHP: 5.2, Propel: 1.3 } |
注释将被YAML解析器直接忽略,毋须“根据集合中的嵌套层级”而刻意缩进。
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。