前言
YAML 并不是一种新奇的语言,YAML 首次发表于 2001 年,距离现在已经过去差不多 20 个年头。YAML 虽然不如 JSON、XML 之类的语言流行,应用也没有那么广泛,但是 YAML 也有它的优势。
简介
YAML 是一种较为人性化的数据序列化语言,可以配合目前大多数编程语言使用。YAML 的语法比较简洁直观,特点是使用空格来表达层次结构,其最大优势在于数据结构方面的表达,所以 YAML 更多应用于编写配置文件,其文件一般以 .yml 为后缀。
基本语法
· 大小写敏感
- 就是字面上的意思
One: 1 one: 2
-
用缩进表示层级关系
- 缩进只能使用空格,不能用 TAB 字符
- 缩进的空格数量不重要,但是同一层级的元素左侧必须对齐
# YAML one: two: 2 three: four: 4 five: 5 // 以上的内容转成 JSON 后 "one": { "two": 2, "three": { "four": 4, "five": 5 } }
-
用 # 表示注释
——只支持单行注释
# 我是注释 # 我也是注释
-
一个文件中可以包含多个文件的内容
- 用“ --- ”即三个破折号表示一份内容的开始
- 用“ ... ”即三个小数点表示一份内容的结束(非必需)
--- # 这是第一份内容 one: 1 # 其他内容... ... --- # 这是第二份内容 two: 2 # 其他内容...
数据结构与类型
· 对象(Mapping)
- 表示以键值对(key: value)形式出现的数据
- -使用“冒号+空格”来分开键与值
# YAML key: value // JSON "key": "value"
- 支持多层嵌套(用缩进表示层级关系)
# YAML key: child-key1: value1 child-key2: value2 // JSON "key": { "child-key1": "value1", "child-key2": "value2", }
- 支持流式风格( Flow style)的语法(用花括号包裹,用逗号加空格分隔,类似 JSON)
# YAML key: { child-key1: value1, child-key2: value2 } // JSON "key": { "child-key1": "value1", "child-key2": "value2" }
- - 使用问号“?”声明一个复杂对象,允许你使用多个词汇(数组)来组成键
# YAML key: { child-key1: value1, child-key2: value2 } // JSON "key": { "child-key1": "value1", "child-key2": "value2" }
- 使用问号“?”声明一个复杂对象,允许你使用多个词汇(数组)来组成键
# YAML ? - keypart1 - keypart2 : - value1 - value2
数组(Sequence)
- 组以区块格式(Block Format)(即“破折号+空格”)开头的数据组成一个数组
# YAML values: - value1 - value2 - value3 // JSON "values": ["value1", "value2", "value3"]
- 同时也支持内联格式(Inline Format)来表达(用方括号包裹,逗号加空格分隔,类似 JSON)
# YAML values: [value1, value2, value3] // JSON "values": ["value1", "value2", "value3"]
- 支持多维数组(用缩进表示层级关系)
# YAML values: - - value1 - value2 - - value3 - value4 // JSON "values": [[ "value1", "value2"], ["value3", "value4"]]
标量(Scalars)
- 表示 YAML 中最基本的数据类型- 字符串(String)
1、字符串一般不需要用引号包裹,但是如果字符串中使用了反斜杠“\”开头的转义字符就必须使用引号包裹
# YAML strings: - Hello without quote # 不用引号包裹 - Hello world # 拆成多行后会自动在中间添加空格 - 'Hello with single quotes' # 单引号包裹 - "Hello with double quotes" # 双引号包裹 - "I am fine. \u263A" # 使用双引号包裹时支持 Unicode 编码 - "\x0d\x0a is \r\n" # 使用双引号包裹时还支持 Hex 编码 - 'He said: "Hello!"' # 单双引号支持嵌套" // JSON "strings": ["Hello without quote", "Hello world", "Hello with single quotes", "Hello with double quotes", "I am fine. ☺", "\r\n is \r\n", "He said: 'Hello!'"]
2. 对于多行的文字,YAML 提供了两种特殊的语法支持
保留换行(Newlines preserved)
> 使用竖线符“ | ”来表示该语法,每行的缩进和行尾空白都会被去掉,而额外的缩进会被保留
# YAML lines: | 我是第一行 我是第二行 我是吴彦祖 我是第四行 我是第五行 // JSON "lines": "我是第一行\n我是第二行\n 我是吴彦祖\n 我是第四行\n我是第五行"
-
折叠换行(Newlines folded)
> 使用右尖括号“ > ”来表示该语法,只有空白行才会被识别为换行,原来的换行符都会被转换成空格
# YAML lines: > 我是第一行 我也是第一行 我仍是第一行 我依旧是第一行 我是第二行 这么巧我也是第二行 // JSON "lines": "我是第一行 我也是第一行 我仍是第一行 我依旧是第一行\n我是第二行 这么巧我也是第二行"
-
布尔值(Boolean)
1. “true”、“True”、“TRUE”、“yes”、“Yes”和“YES”皆为真
2. “false”、“False”、“FALSE”、“no”、“No”和“NO”皆为假
# YAML boolean: - true # True、TRUE - yes # Yes、YES - false # False、FALSE - no # No、NO // JSON "boolean": [true, true, false, false]
-
整数(Integer)
支持二进制表示
# YAML int: - 666 - 0001_0000 # 二进制表示 // JSON "int": [666, 4096]
-
浮点数(Floating Point)
支持科学计数法
# YAML float: - 3.14 - 6.8523015e+5 # 使用科学计数法 // JSON "float": [3.14, 685230.15]
-
空(Null)
“null”、“Null”和“~”都是空,不指定值默认也是空
# YAML nulls: - null - Null - ~ - // JSON "nulls": [null, null, null, null]
- 时间戳(Timestamp)
YAML 也支持 ISO 8601 格式的时间数据
> 这里使用 JavaScript 对象进行对比
# YAML date1: 2020-05-26 date2: 2020-05-26T01:00:00+08:00 dete3: 2020-05-26T02:00:00.10+08:00 date4: 2020-05-26 03:00:00.10 +8 // JavaScript date1: Tue May 26 2020 08:00:00 GMT+0800 (中国标准时间), date2: Tue May 26 2020 01:00:00 GMT+0800 (中国标准时间), dete3: Tue May 26 2020 02:00:00 GMT+0800 (中国标准时间), date4: Tue May 26 2020 03:00:00 GMT+0800 (中国标准时间)
类型转换
YAML 支持使用严格类型标签“!!”(双感叹号+目标类型)来强制转换类型
# YAML a: !!float '666' # !! 为严格类型标签 b: '666' # 其实双引号也算是类型转换符 c: !!str 666 # 整数转为字符串 d: !!str 666.66 # 浮点数转为字符串 e: !!str true # 布尔值转为字符串 f: !!str yes # 布尔值转为字符串 // JSON "a": 666, "b": "666", "c": "666", "d": "666.66", "e": "true" "f": "yes"
其他高级类型
YAML 也可以使用一些更高级的类型,但是并不一定兼容所有解析器,包括集合(Sets)、有序映射(Ordered Map)、十六进制数据(Hexdecimal)和二进制数据(Binary)。
本文将不会对这几种类型进行讲解,感兴趣的读者可以自行搜索研究。
数据重用与合并
为了保持内容的简洁,避免过多重复的定义,YAML 提供了由锚点标签“&”和引用标签“*”组成的语法,利用这套语法可以快速引用相同的一些数据...
// YAML a: &anchor # 设置锚点 one: 1 two: 2 three: 3 b: *anchor # 引用锚点 // JSON "a": { "one": 1, "two": 2, "three": 3 }, "b": { "one": 1, "two": 2, "three": 3
配合合并标签“<<”使用可以与任意数据进行合并,你可以把这套操作想象成面向对象语言中的继承...
# YAML human: &base # 添加名为 base 的锚点 body: 1 hair: 999 singer: <<: *base # 引用 base 锚点,实例化时会自动展开 skill: sing # 添加额外的属性 programer: <<: *base # 引用 base 锚点,实例化时会自动展开 hair: 6 # 覆写 base 中的属性 skill: code # 添加额外的属性 // JSON "human": { "body": 1, "hair": 999 }, "singer": { "body": 1, "hair": 999, "skill": "sing" }, "programer": { "body": 1, "hair": 6, "skill": "code" }
相关链接:
- YAML 官方网站:https://yaml.org
- YAML 1.2 官方文档:https://yaml.org/spec/1.2/spec.html
- YAML - *:https://zh.wikipedia.org/wiki/YAML
- YAML to JSON (格式在线转换):https://www.json2yaml.com/convert-yaml-to-json