YAML 语法随笔
文章目录
- 1_基本语法格式要求
- 2_数据类型
- 2.1 字符串
- 2.2 数值
- 2.3 布尔值
- 2.4 空值
- 2.5 列表 (Array)
- 2.6 对象/字典 (Map)
- 2.7 日期时间类型
- 3_强制类型转换
- 4_YAML 复杂数据结构示例
- 4.1 嵌套结构
- 4.2 列表包含字典
- 4.3 字典包含列表
- 4.4 复用锚点和引用
- 5_YAML 字面量和折叠字符串
- 6_特殊符号和转义字符
- 7_多个YAML配置放在同一文件中
- 8_YAML 文件示例
- 9_YAML 实践建议
- 10_YAML 常见应用场景
- 11_总结
YAML (YAML Ain’t Markup Language) 是一种简洁、易读、类似 XML、JSON 的标记性语言。它强调以数据为中心,广泛用于配置文件和数据交换。
YAML 结构化、可读性强,是 Kubernetes、Ansible 等工具的主要配置语言。
1_基本语法格式要求
-
缩进:
YAML 使用缩进来表示层级关系,通常使用两个空格缩进。
低版本限制,不能使用制表符
Tab
。缩进的空格数不重要,只要相同层级的元素左对齐即可。
-
区分大小写:
name
和Name
是两个不同的键。 -
文件扩展名:YAML 文件通常使用
.yaml
或.yml
扩展名。 -
注释:使用
#
表示注释,注释内容不会被解析。# This is a comment key: value
2_数据类型
YAML支持以下几种数据类型:
- 纯量:单个的、不可再分的值(基本数据类型、日期、null、字符串等)
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hash) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
总的来说包含这几种:字符串、数值、布尔值、空值、日期时间、列表和字典。
2.1 字符串
直接字符串:键值对中的值默认为字符串。
带引号字符串:可以使用单引号或双引号。
-
双引号允许使用转义字符,单引号则不支持(双引号不会对特殊字符转义)。
-
如果字符串之中包含空格或特殊字符,需要放在引号之中。
# 不带引号的字符串
key1: value
# 单引号字符串
key2: 'single-quoted string'
# 双引号字符串
key3: "double-quoted string with newline \n"
# 单引号会对\n进行的操作
key2: 'string\n' # ->>> "string\\n"
多行字符串:使用 |
表示保留换行,使用 >
表示折叠换行。
# 保留换行
multiline: |
line1
line2
# 折叠换行
folded: >
line1
line2
字符串可以拆成多行,从第二行开始,必须有一个单空格缩进(换行符会被转为空格)。
multiline: line1
line2
单引号之中如果还有单引号,必须连续使用两个单引号转义。
str: 'labor''s day'
2.2 数值
YAML 支持整数和浮点数,可以直接写数值而不需引号。
integer: 42
float: 3.14159
negative: -5
2.3 布尔值
布尔值使用 true
、false
、yes
、no
、on
、off
等关键字,均不区分大小写,比如True
也可以使用。
is_enabled: true
has_access: no
2.4 空值
空值使用 null
、 ~
或者什么都不添加进行表示。
value1: null
value2: ~
value3:
2.5 列表 (Array)
列表使用 -
连词线开头表示元素,每个元素在新行,构成一个数组。
fruits:
- apple
- banana
- orange
也可以在一行内表示列表(行内表示法 ):
colors: [red, green, blue]
2.6 对象/字典 (Map)
对象又叫字典,表示键值对,值可以是任何数据类型,使用冒号结构表示。
person:
name: Alice
age: 30
email: alice@example.com
还可以使用类似 JSON 的形式声明:
person: { name: Alice, age: 30 }
2.7 日期时间类型
YAML 支持标准的日期和时间格式,通常遵循 ISO 8601 格式。例如,日期可以写成 YYYY-MM-DD
格式,时间可以写成 YYYY-MM-DD HH:MM:SS
或 YYYY-MM-DDTHH:MM:SSZ
格式。
日期示例:
start_date: 2024-11-08
日期和时间示例(带时区,对应 Java 语言中的 ZonedDateTime):
start_time: 2024-11-08T14:30:00Z
Z
表示 UTC 时间。- 还可以在时间后面指定时区偏移,例如
+02:00
。
YAML 会自动识别这种格式并将其解析为日期或时间类型。
如果解析器不支持日期时间解析,可以将日期或时间用引号括起来,明确将其作为字符串处理:
event_date: "2024-11-08"
3_强制类型转换
在 YAML 中,类型一般是隐式推断的,但我们可以通过强制类型转换来显式指定某个值的类型。
YAML 支持的强制类型转换可以确保数据按照指定类型进行处理,主要通过 !!
标签来实现。
YAML 中常用的类型标签包括:
常用标签 | 作用 |
---|---|
!!str | 强制转换为字符串类型 |
!!int | 强制转换为整数类型 |
!!float | 强制转换为浮点数类型 |
!!bool | 强制转换为布尔类型 |
!!null | 强制转换为空值类型 |
!!seq | 强制转换为序列(即列表)类型 |
!!map | 强制转换为映射(即字典)类型 |
# 将值强制转换为字符串
is_enabled: !!str yes # 强制将 yes 作为字符串处理
value: !!str 123 # 强制将 123 作为字符串处理
# 将值强制转换为整数
integer_value: !!int "123" # 强制将 "123" 转为整数
# 强制转换为浮点数:
float_value: !!float "3.14" # 强制将 "3.14" 转换为浮点数
# 将值强制转换为布尔类型
bool_value1: !!bool "yes" # 强制将 "yes" 转为布尔值 true
bool_value2: !!bool "false" # 强制将 "false" 转为布尔值 false
# 将值强制转换为空值
empty_value: !!null "" # 将空字符串强制转换为空
# 强制转换为序列
my_list: !!seq
- item1
- item2
# 强制转换为映射
my_map: !!map
key1: value1
key2: value2
注意事项:
- 强制类型转换标签会覆盖 YAML 的自动类型推断。
- 一些 YAML 解析器可能不支持所有类型的强制转换标签(如
!!seq
和!!map
),使用时需要确保与所用工具兼容。
通过使用强制类型转换可以明确数据的类型,避免误解或错误解析。
4_YAML 复杂数据结构示例
4.1 嵌套结构
YAML 支持嵌套结构,可用于表示多层级的数据关系。
database:
host: localhost
port: 3306
credentials:
username: admin
password: secret
4.2 列表包含字典
可以在列表中包含字典,以表示复杂的对象集合。
users:
- name: Alice
age: 30
- name: Bob
age: 25
4.3 字典包含列表
可以在字典中包含列表,适用于同一个键有多个值的情况。
departments:
sales:
- John Doe
- Jane Smith
engineering:
- Alice Brown
- Bob White
4.4 复用锚点和引用
YAML 提供了锚点 &
和引用 *
,可用于复用相同的值。
defaults: &defaults
timeout: 30
retries: 5
production:
<<: *defaults
timeout: 60
在上例中,production
将继承 defaults
的值,并覆盖 timeout
,转为 JSON 对应的值如下:
{
"defaults": {
"timeout": 30,
"retries": 5
},
"production": {
"timeout": 60,
"retries": 5
}
}
5_YAML 字面量和折叠字符串
YAML 支持字面量和折叠字符串,用于表示多行文本。
-
字面量字符串 (
|
):保留多行文本中的换行。description: | This is a multi-line string with line breaks.
-
折叠字符串 (
>
):折叠多行文本,所有行会合并成一个段落。description: > This is a multi-line string without line breaks.
6_特殊符号和转义字符
在 YAML 中,有一些特殊字符需要转义处理。
-
双引号 (
"
):允许使用转义字符。 -
反斜杠 (
\
):用于转义,如\n
表示换行。escaped: "This is a double-quoted string with a newline \n character"
7_多个YAML配置放在同一文件中
在实际应用中,我们有时需要在一个文件中包含多个 YAML 文档。可以使用 ---
(三个连字符)作为分隔符,将不同的文档分隔开。
每个文档可以有自己的顶层键结构或内容。
# 第一个文档
app_config:
name: "Application 1"
version: 1.0
# 文档分隔符
---
# 第二个文档
app_config:
name: "Application 2"
version: 2.0
database:
host: "localhost"
port: 5432
- 每个文档以
---
开头,表示一个新的 YAML 文档。 - 您可以在同一个文件中包含多个配置,通常用于配置文件包含多个环境或多种资源定义的场景。
在 Kubernetes、Ansible 等工具中,多个配置常被放在同一文件中,用 ---
分隔来定义不同的资源或任务。
8_YAML 文件示例
以下是一个完整的 YAML 配置文件示例,涵盖了多种数据类型和结构:
# 配置文件示例
app_config:
name: "Sample Application"
version: 1.0
enabled: true
timeout: null
# 数据库配置
database:
host: "localhost"
port: 5432
username: "admin"
password: "secret"
options:
reconnect: true
pool_size: 20
# 支持的语言
supported_languages:
- "en"
- "fr"
- "es"
# 日志配置
logging:
level: "INFO"
format: |
timestamp: "%Y-%m-%d %H:%M:%S"
message: "Log message format with multi-line support"
outputs:
- "console"
- "file"
9_YAML 实践建议
-
适当使用注释:为配置项增加注释以提高可读性。
-
层级结构清晰:合理设计层级结构,避免过深嵌套。
-
缩进错误:缩进需一致,通常为 2 个空格,老版本不允许使用
Tab
。 -
键重复:同一层级的键不能重复,否则解析器会报错。
-
保留空格:使用
|
或>
时,应确保空格正确,以避免内容解析错误。 -
书写空格:书写 yaml 切记
:
后面要加一个空格。 -
格式验证:YAML转JSON网址,可用于验证YAML书写是否正确。
10_YAML 常见应用场景
- Kubernetes 配置:用于定义 Pod、Service、Deployment 等资源。
- Ansible Playbooks:用于定义任务和角色。
- CI/CD 配置:例如 GitHub Actions 的
.yml
配置文件。
11_总结
编写本篇内容的目的主要是可以在声明配置文件时方便查阅,提高效率。