YAML语法说明

现代编程中,少不了编写配置文件,常用的配置文件编写格式有:xmljson,在前端工程化开发中,甚至还有使用 js 作为配置文件的。
本文将介绍一种更适合编写配置的语言 YAML(Yet Another Markup Language)。并记录其标准语法。

前言

YAML 的语法和其他高级语言类似,并且可以简单表达 清单(数组)、散列表(对象),标量(纯量) 等数据形态。它使用 空白符号 缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和 YAML 非常接近)。

YAML 的配置文件后缀为 .yml,如:_config.yml

基本语法规则

1
2
3
4
5
1. 大小写敏感。
2. 使用缩进表示层级关系。
3. 缩进时不允许使用 Tab 键,只允许使用空格。
4. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可。
5. 键值对之间,一定要存在空格。

注释

YAML 中,使用 # 进行注释标识。以 # 开头的行都会被解析器忽略。

1
# 我是一行注释

支持的数据结构

YAML 支持的数据结构有 3 种。

1
2
3
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
纯量(scalars):单个的、不可再分的值

接下来,介绍他们各自的书写语法。并以 js-yaml 的实现为例进行讲解。

对象

YAML 中,对象的一组键值对,使用 : 冒号结构进行表示。

1
foo: hello yaml

转换为 javascript 如下。

1
2
3
{
foo: 'hello yaml'
}

除了使用上面的语法,还支持将所有键值对写成一个行内对象的形式。

1
foo: { name: little hong, age: 18 }

转换为 javascript 如下。

1
2
3
4
5
6
{
foo: {
name: 'little hong',
age: 18
}
}

数组

YAML 中,使用一组连词线 - 开头的行,构成一个数组。

1
2
3
- little hong
- elenh
- yisibell

转换为 javascript 如下。

1
['little hong', 'elenh', 'yisibell']

如果想继续嵌套层级,使其有多维数组形式,可以使用 空格 (注意,不可使用 Tab 键)进行表示。

1
2
3
4
- 
- little hong
- elenh
- yisibell

转换为 javascript 如下。

1
2
3
[
['little hong', 'elenh', 'yisibell']
]

同样的,数组类型,也可以使用行内表示方式。

1
elenh: [little, hong, 18]

转换为 javascript 如下。

1
2
3
{
elenh: ['little', 'hong', 18]
}

复合结构

对象,数组可以结合使用,形成复合结构。

1
2
3
4
5
6
7
8
9
languages:
- Ruby
- Perl
- Python
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org

转换为 javascript 如下。

1
2
3
4
5
6
7
8
9
{ 
languages: [ 'Ruby', 'Perl', 'Python' ],
websites: {
YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org'
}
}

纯量

纯量是最基本的、不可再分的值。以下数据类型都属于 JavaScript 的纯量。

1
2
3
4
5
6
7
1. 字符串
2. 布尔值
3. 整数
4. 浮点数
5. Null
6. 时间
7. 日期

数值

数值直接以字面量的形式表示。

1
number: 12.30

转为 javaScript 如下。

1
2
3
{ 
number: 12.30
}

布尔值

布尔值用 truefalse 表示。

1
isSet: true

转为 javaScript 如下。

1
2
3
{ 
isSet: true
}

null

null~ 表示。

1
parent: ~ 

转为 javaScript 如下。

1
2
3
{ 
parent: null
}

时间

时间采用 ISO8601 格式。

1
iso8601: 2001-12-14t21:59:43.10-05:00 

转为 javaScript 如下。

1
2
3
{ 
iso8601: new Date('2001-12-14t21:59:43.10-05:00')
}

日期

日期采用复合 iso8601 格式的 年、月、日 表示。

1
date: 1976-07-31

转为 javaScript 如下。

1
2
3
{ 
date: new Date('1976-07-31')
}

转换

YAML 允许使用 两个感叹号强制转换 数据类型。

1
2
e: !!str 123
f: !!str true

转为 javaScript 如下。

1
2
3
4
{ 
e: '123',
f: 'true'
}

字符串

字符串 是最常见,也是最复杂的一种数据类型。

字符串默认不使用引号表示。

1
str: 这是一行字符串

转为 javaScript 如下。

1
2
3
{ 
str: '这是一行字符串'
}

注: 如果字符串之中包含空格或特殊字符,需要放在引号之中。

1
str: '内容: 字符串'

转为 javaScript 如下。

1
2
3
{ 
str: '内容: 字符串'
}

单引号和双引号都可以使用,双引号不会对特殊字符转义。

1
2
s1: '内容\n字符串'
s2: "内容\n字符串"

转为 javaScript 如下。

1
2
3
4
{ 
s1: '内容\\n字符串',
s2: '内容\n字符串'
}

单引号之中如果还有单引号,必须连续使用两个单引号转义。

1
str: 'labor''s day' 

转为 javaScript 如下。

1
2
3
{ 
str: 'labor\'s day'
}

字符串可以写成多行,从第二行开始,必须有一个单空格缩进。换行符会被转为空格。

1
2
3
str: 这是一段
多行
字符串

转为 avaScript 如下。

1
2
3
{ 
str: '这是一段 多行 字符串'
}

多行字符串可以使用 | 保留换行符,也可以使用 > 折叠换行。

1
2
3
4
5
6
this: |
Foo
Bar
that: >
Foo
Bar

转为 javaScript 代码如下。

1
2
3
4
{ 
this: 'Foo\nBar\n',
that: 'Foo Bar\n'
}

+ 表示保留文字块末尾的换行,- 表示删除字符串末尾的换行。

1
2
3
4
5
6
7
8
9
s1: |
Foo

s2: |+
Foo


s3: |-
Foo

转为 javaScript 代码如下。

1
2
3
4
5
{ 
s1: 'Foo\n',
s2: 'Foo\n\n\n',
s3: 'Foo'
}

字符串之中可以插入 HTML 标记。

1
2
3
4
5
message: |

<p style="color: red">
段落
</p>

转为 javaScript 如下。

1
2
3
{ 
message: '\n<p style="color: red">\n 段落\n</p>\n'
}

引用

锚点 & 和别名 *,可以用来引用。

1
2
3
4
5
6
7
8
9
10
11
defaults: &defaults
adapter: postgres
host: localhost

development:
database: myapp_development
<<: *defaults

test:
database: myapp_test
<<: *defaults

等同于下面的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
defaults:
adapter: postgres
host: localhost

development:
database: myapp_development
adapter: postgres
host: localhost

test:
database: myapp_test
adapter: postgres
host: localhost

& 用来建立锚点(defaults),<< 表示合并到当前数据,* 用来引用锚点。

下面是另一个例子。

1
2
3
4
5
- &showell Steve 
- Clark
- Brian
- Oren
- *showell

转为 javaScript 代码如下。

1
[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]

函数和正则表达式的转换

这是 js-yaml 库特有的功能,可以把函数和正则表达式转为字符串。

1
2
3
# example.yml
fn: function () { return 1 }
reg: /test/

解析上面的 example.yml 文件的代码如下。

1
2
3
4
5
6
7
8
9
10
11
var yaml = require('js-yaml');
var fs = require('fs');

try {
var doc = yaml.load(
fs.readFileSync('./example.yml', 'utf8')
);
console.log(doc);
} catch (e) {
console.log(e);
}

javaScript 对象还原到 yml 文件的代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var yaml = require('js-yaml');
var fs = require('fs');

var obj = {
fn: function () { return 1 },
reg: /test/
};

try {
fs.writeFileSync(
'./example.yml',
yaml.dump(obj),
'utf8'
);
} catch (e) {
console.log(e);
}

好了,以上就是全部内容,玩得开心!