01-YAML 简介和语法

0、一些网站

1、YAML 简介

YAMLYAML Ain't Markup LanguageYAML不是一种标记语言的缩写)是一种人类可读的完整的数据序列化语言。

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

  • 文件的标准扩展名为 .yaml,也可接受.yml扩展名;
  • YAML基本语法规则(基于缩进的Block Style):
    • 大小写敏感;
    • 使用缩进表示层级关系(类似Python风格);
    • 缩进不允许使用Tab制表符,只允许使用空格字符;
    • 缩进的空格数不重要,但官方推荐使用2个空格字符;
  • YAML基本语法规则(基于显式指示符的表示范围的Flow Style):
    • 流序列:以逗号分隔的列表形式写入,并置于方括号[]内;
    • 流映射:以逗号分隔的列表形式写入,并置于大括号{}内;
  • YAML支持3种基本数据类型:
    • 标量(Scalar):原子数据类型,如:字符串(String)、数字(Numbers)、布尔值(Boolean)和空值(null)等;
    • 序列(Sequence):节点列表,类似某些编程语言的数组(Array)、列表(List)等;
    • 映射(Mapping):节点到节点的映射,键值对,类似某些编程语言的哈希(Hash)、哈希映射(Hash Map)、字典(Dict)、对象(Objects)等;
      与许多编程语言不同,键key可以是序列或映射。
  • 一个YAML文件或流可以包含多个文档Documents
    • 文档可以显式地以---开头(可选的)。在规范中称此为指令结束标记,但实际使用中更多称为文档开始标记
    • 文档可以显式地以...结尾(可选的)。在规范中称此为文档结束标记,如果文档没有指令,可以省略---,仅用...来分割多个文档;
    • 如果YAML文件或流仅包含一个文档,那么--- ...可以省略
  • YAML支持两个指令:
    • 版本指令:指令放在---之前行,如 %YAML 1.2 用于告知 YAML 处理器使用哪个版本处理当前文档;
    • 标签指令:为用户提供自定义处理程序的速记标记的方法,一般很少使用

2、YMAL 语法

2.1、注释

YAML 允许使用注释,注释以“#”开头,直到行尾都是注释。注释可以用来解释代码或者标记代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 这是一条注释
name: John Doe # 这是一个属性值

# 需要注意的是:在块标量中,缩进正确的以#开头的行,不会被解释为注释
test1: |
a
# no comment
b
# 等效于 test1: "a\n# no comment\nb\n"


# 缩进不正确的以#开头的行,会被解释为注释,并结束当前块标量
test2: >
a
b
# a comment, end of block scalar
# 等效于 test2: "a b\n"


# 可以直接在标头之后向块标量添加注释
literal: | # a block scalar
abc
def
folded: > # a block scalar
abc
def
...

2.2、标量(Scalar)

YMAL 中标量是最基本的不可再分割的值,如 字符串(String)、数字(Numbers)、布尔值(Boolean)和空值(null)等。

其中最常见也是最复杂的是字符串(String)。基本上有五种方式来表达字符串:

  • 流标量Flow Scalars:(普通标量、单引号标量、双引号标量)
  • 块标量Block Scalars:(文本块标量、折叠块标量)

2.2.1、流标量 Flow Scalars

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 普通标量:不带引号的字符串
a string: no quotes needed

# 标量也可以用多行表示法,如下:使用回车的多行,最终连接成一行
multi lines string:
first line,
second line.


# 单引号标量:使用单引号括起来的字符串
# 单引号标量字符串中,除'单引号之外的任何字符都将按字面返回,不能使用转义字符进行转义
a single quoted string: '&enclosed in single quotes'
# 单引号标量字符串中,如果有'单引号,可以通过加倍进行转义
a single quoted string contained single quote: 'with one single '' quote'


# 双引号标量:使用双引号括起来的字符串
# 双引号标量字符串中,反斜杠\将作为转义字符
a double quoted string: "here's a \t tab and a \n newline,
followed by a \\ backslash"
another double quoted string: "with an escaped \" double quote"
# 需要注意的是,可转义的字符序列有限,详情请参考:http://yaml.org/spec/1.2/spec.html#id2776092
# 另外,反斜杠\还有另外的一个含义-换行,当想将长字符串分成几行同时向保留行尾的空格,这很有用
multi:
"the first line ends with 5 spaces \
second line"
single: "the first line ends with 5 spaces second line"

不能在普通标量开头使用的字符(YAML语法元素):

  • ! Tag 标记符, 如 !!null
  • & 锚点 符,如 &mapping_for_later_use
  • * 别名引用 符,如 *mapping_for_later_use
  • -<space> 流序列 符
  • :<space> 流映射 符
  • ?<space> 复杂key声明符
  • { } [ ] 流映射及流序列 符
  • , 流收集条目分隔符
  • # 注释符
  • | > 块标量
  • @ ```(反引号)保留字符
  • " ' 双引号和单引号
  • <space>
  • % 指令符

不能在普通标量中间使用的字符序列:

  • :<space> 键/值分隔符。允许使用冒号,但前提是不允许后跟空格
  • <space># 这将开始评论

2.2.2、块标量 Block Scalars

当字符串较长时,最好使用块标量 来使其更具可读性。

块标量的一个优点是,在其内部的任何字符序列都是被允许的,不存在转义的情况。

(除了用于缩进的空格,行开头或结尾的空格将被保留。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
%YAML 1.2
# 文本块标量(Literal Block Scalar)
# 文本块标量通过|管道符引入,内容开始在下一行,并且必须有缩进
# 从块标量的第一(非空)行检测到缩进。行开头或结尾的空格以及换行符将被保留
literal: |
line 1
line 2
end
# 等效于
quoted: "line 1\n line 2\nend\n"
...


%YAML 1.2
# 折叠块标量(Folded Block Scalar)
# 折叠块标量通过>符合引入,内容开始在下一行,并且必须有缩进
# 使用空格将多行进行折叠,可以使用空行强制执行换行符
a text with long lines: >
this is the first
long line

and this is the
second
# 等效于
quoted: "this is the first long line\nand this is the second\n"
...


%YAML 1.2
# 前导空行(包含仅有空格的行),将会被保留,下例中 为了更容易识别,用--表示空格仅含空格的行
# 尾随空行(包含仅有空格的行),不会被保留
folded: >

--
a
b
--

# 等效于
quoted: "\n\na b\n" # 这里b后的\n,不是从尾随空行来的,而是块标量必有的
...


%YAML 1.2
# 如果你不想 块标量总是以换行符结尾,你可以使用-指示符
literal: |-
a
b
# 等效于 "a\nb"

folded: >-
a
b
# 等效于 "a b"
...


%YAML 1.2
# 如果你不想 保留块标量所有的尾随换行符,你可以使用+指示符
literal: |+
a
b
# 等效于: "a\nb\n\n\n"


folded: >+
a
b
# 等效于: "a b\n\n\n"
...

2.3、映射(Mapping)

YAML 以键值对形式存储数据,以: 分隔键和值。: 和值之间必须有一个空格。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
%YAML 1.2
# 简单的映射
name: John Doe
age: 28


# 使用缩进表示层次关系(Block Style)
person:
name: John Doe
age: 28
address:
city: New York
state: NY
# 使用紧凑型的表示如下(Flow Style)同一级别放在同一对{}内,键值对之间用英文逗号,隔开
{person: {name: John Doe, age: 28, address: {city: New York, state: NY}}}


# 如果键key是序列、映射类型的复杂键,需要使用 ? 来标记
# 如 使用序列作为键
? [blue, reg, green]: Color
# 等效于
? - blue
- reg
- gree
: Color
...

2.4、序列(Sequence)

YAML 支持序列(列表),以-开头,后跟一个空格和列表项的值。列表项可以是任何类型的数据,标量、序列、映射等。

- 之前是否缩进2个空格看个人习惯,官网上有的地方缩进了,有的地方没缩进

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
%YAML 1.2
# Block Style
fruits:
- apple
- orange
- banana
# 等效于(Flow Style)同一级别放在同一对[]内,各项之间用英文逗号,隔开
# fruits: [apple,orange,banana]


# 序列和映射类型可以组合使用,形成符合结构
languages:
- Ruby
- Perl
- Python
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org
...

2.5、锚点(Anchor)与别名(Alias)

YAML 支持使用锚点(Anchor)与别名(Alias)来避免重复定义数据。可以使用&定义一个锚点,使用*引用已定义的锚点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 在使用别名之前必须创建一个锚点
invoice number: 314159
name: Santa Claus

shipping address: &address # Anchor
street: Santa Claus Lane # ┐
zip: 12345 # │ Anchor content
city: North Pole # ┘
billing address: *address # Alias


# 另一个锚点与别名的示例
hr:
- Mark McGwire
- &SS Sammy Sosa # Anchor
rbi:
- *SS # Alias
- Ken Griffey

2.6、继承

YAML 支持继承数据。可以使用<<表示继承锚点数据(仅继承未有的数据部分)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
defaults: &defaults
name: John Doe
age: 18

person1:
<<: *defaults
name: Shirley
...
# 等效于 (保留已有的数据,继承未有的数据)
defaults:
name: John Doe
age: 18

person1:
name: Shirley
age: 18

01-YAML 简介和语法
https://flepeng.github.io/021-YAML-01-YAML-简介和语法/
作者
Lepeng
发布于
2021年3月12日
许可协议