YAML格式

3.4 版本
维护中的版本

根据 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

最后,还有其他一些场合需要引号,不管你使用双引还是单引:

  • 当字符串是 truefalse (否则,它将被当作布尔值对待);
  • 当字符串是 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代码:

1
2
3
4
5
6
7
8
9
10
array(
    'symfony 1.0' => array(
        'PHP'    => 5.0,
        'Propel' => 1.2,
    ),
    'symfony 1.2' => array(
        'PHP'    => 5.2,
        'Propel' => 1.3,
    ),
);

在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 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)