一文看懂 YAML
前言
YAML 并不是一種新奇的語言,YAML 首次發表于 2001 年,距離現在已經過去差不多 20 個年頭。YAML 雖然不如 JSON、XML 之類的語言流行,應用也沒有那么廣泛,但是 YAML 也有它的優勢。
互聯網上的關于 YAML 的文章雖然不多,但也足以讓人了解這一款語言,那我為什么還要寫這一片入門文章呢?
我認為現有的文章有以下幾點不足:
內容碎片化,閱讀起來不夠流暢
講解較為生硬,閱讀起來比較費勁
缺少對比,難以讓人快速理解
所以本篇文章的主要目的就是讓讀者能夠快速并準確地了解這款語言,事不宜遲,讓我們開始吧!
為了幫助理解,我將在文中穿插相對應的 JSON 格式的內容作為對比。
可能是東半球最通俗易懂的 YAML 中文講解之一(手動狗頭)
簡介
YAML 是一種較為人性化的數據序列化語言,可以配合目前大多數編程語言使用。
YAML 的語法比較簡潔直觀,特點是使用空格來表達層次結構,其最大優勢在于數據結構方面的表達,所以 YAML 更多應用于編寫配置文件,其文件一般以 .yml 為后綴。
YAML 目前的官方全稱為 “YAML Ain't Markup Language(YAML 不是標記語言)”,但有意思的是,其實 YAML 最初的含義是 “Yet Another Markup Language(還是一種標記語言)”。
目前 YAML 的最新版本為 1.2(第三個版本),本文將以 YAML 1.2 的標準進行講解。
正文
基本語法
大小寫敏感
就是字面上的意思
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
?
- 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)
字符串一般不需要用引號包裹,但是如果字符串中使用了反斜杠“\”開頭的轉義字符就必須使用引號包裹
# 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!'" ]
對于多行的文字,YAML 提供了兩種特殊的語法支持:
保留換行(Newlines preserved)
使用豎線符“ | ”來表示該語法,每行的縮進和行尾空白都會被去掉,而額外的縮進會被保留
# YAML
lines: |
我是第一行
我是第二行
我是吳彥祖
我是第四行
我是第五行
// JSON
"lines": "我是第一行\n我是第二行\n 我是吳彥祖\n 我是第四行\n我是第五行"
折疊換行(Newlines folded)
使用右尖括號“ > ”來表示該語法,只有空白行才會被識別為換行,原來的換行符都會被轉換成空格
# YAML
lines: >
我是第一行
我也是第一行
我仍是第一行
我依舊是第一行
我是第二行
這么巧我也是第二行
// JSON
"lines": "我是第一行 我也是第一行 我仍是第一行 我依舊是第一行\n我是第二行 這么巧我也是第二行"
布爾值(Boolean)
“true”、“True”、“TRUE”、“yes”、“Yes”和“YES”皆為真
“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
傳送門
微信推文版本
個人博客:菜鳥小棧
開源主頁:陳皮皮
Eazax-CCC 游戲開發腳手架
更多分享
為什么選擇使用 TypeScript ?
高斯模糊 Shader
公眾號
菜鳥小棧
我是陳皮皮,這是我的個人公眾號,專注但不僅限于游戲開發、前端和后端技術記錄與分享。
每一篇原創都非常用心,你的關注就是我原創的動力!
Input and output.
專注但不僅限于游戲開發和前端技術分享...
總結
- 上一篇: 重装系统时,将MBR分区转为GPT 分区
- 下一篇: 写山的诗句(122首描写山水风光的诗词名