YAML語法
YAML 語法
0.線上工具:yaml 校驗工具
- yaml 轉 JS
- yaml 轉 json(格式互轉)
- yaml 線上編輯
- json 格式轉換
1.簡介
-
在資料格式描述和較複雜資料內容展示方面的配置檔案,JSON 能夠很好的支援,包括語法突出顯示、自動格式化、驗證工具等。但是 無法註釋,過於嚴格,長字串轉換會出現問題所以 YAML 可以很好的解決這些問題
-
YAML 是 "YAML Ain't a Markup Language"(YAML 不是一種標記語言)的遞迴縮寫,幾乎是 JSON 的超集,已經被用在一些著名的專案中,如 Travis CI、Circle CI 和 AWS CloudFormation。
-
YAML 語言(發音 /ˈjæməl/ )的設計目標,就是方便人類讀寫。它實質上是一種通用的資料序列化格式。
-
YAML 的庫幾乎和 JSON 一樣無處不在。除了支援註釋、換行符分隔、多行字串、裸字串和更靈活的型別系統之外,YAML 也支援引用檔案,以避免重複程式碼。
-
YAML 有一個小的怪癖。所有的 YAML 檔案開始行都應該是 ---,這是 YAML 格式的一部分,表明一個檔案的開始。
-
YAML 的配置檔案字尾為 yml 或者 yaml
-
YAML 基本語法規則如下。
大小寫敏感
使用縮排表示層級關係,縮排時只允許使用空格,不允許使用 Tab 鍵
縮排的空格數目不重要,只要相同層級的元素左側對齊即可,建議至少 2 個空格
符號 # 表示註釋,從這個字元一直到行尾,都會被解析器忽略。
- YAML 支援的資料結構有三種
物件:鍵值對的集合,又稱為對映(mapping)/ 雜湊(hashes) / 字典(dictionary)
陣列:一組按次序排列的值,又稱為序列(sequence) / 列表(list)
純量(scalars):單個的、不可再分的值
2.YAML 物件寫法
2.1.yaml 基礎物件寫法
- 一組鍵值對使用冒號結構隔開,冒號後面要加一個空格
key: value
- 例項演示:簡單的示例
---
value0: 'hello World!'
value1: "hello World!"
value2: hello World!
-------------------------------
# 轉為 JavaScript 格式
{ value0: 'hello World!',
value1: 'hello World!',
value2: 'hello World!' }
# 轉換為 json 格式
{
"value0": "hello World!",
"value1": "hello World!",
"value2": "hello World!"
}
2.2.單行寫法
- 使用以下樣式,將所有鍵值對寫成一個行內物件
key: { key1: value1, key2: value2, ...}
- 例項演示:
key: { name: zuiyoujie, age: 20 }
2.3.多行寫法
- 使用換行和縮排的寫法可以清晰展示層級關係
key:
name: zuiyoujie
age: 20
- 單行和多行寫法結果一樣,且都可以轉換格式:
# 轉換轉為 JavaScript 格式
{ key: { name: 'zuiyoujie', age: 20 } }
# 轉換為 json 格式
{
"key": {
"name": "zuiyoujie",
"age": 20
}
}
2.4.複雜物件格式的寫法
- 使用問號加空格代表一個複雜的 key,使用一個冒號加空格代表一個複雜的 value
- 意思是物件的屬性是一個數組 [complexkey1,complexkey2],對應的值也是一個數組 [complexvalue1,complexvalue2]
?
- complexkey1
- complexkey2
:
- complexvalue1
- complexvalue2
3.YAML 陣列寫法
3.1.yaml 單個數組寫法
- 以連字元 - 開頭的行(一組資料)表示構成一個數組:
- 列表中的所有成員都開始於相同的縮排級別,比如IP列表,省市列表
key: [ value1, value2, ...]
- 例項演示:yaml 表示一個列表
# 單行寫法:
china: [ 'beijing', 'shanxi', 'hebei' ]
# 多行寫法:
china:
- beijing
- shanxi
- hebei
----------------------------
# 轉為 JavaScript 格式
{ china: [ 'beijing', 'shanxi', 'hebei' ] }
# 轉為 json 格式
{
"china": [
"beijing",
"shanxi",
"hebei"
]
}
3.2.yaml 多陣列寫法
- 兩個陣列的例子:相對複雜,yaml 表示列表和字典
# 單行寫法:
china: [ { beijing: 222, tianjin: 333, hebei: 444 },{ shanxi: 222, shandong: 333 } ]
# 多行寫法:
china:
- beijing: 222 # 可以在連字元後直接寫引數
tianjin: 333
hebei: 444
- # 也可以連字元分隔,換行寫引數
shanxi: 222
shandong: 333
--------------------------
# 轉換為js格式
{ china:
[ { beijing: 222, tianjin: 333, hebei: 444 },
{ shanxi: 222, shandong: 333 } ] }
# 轉換為 json 格式
{
"china": [
{
"beijing": 222,
"tianjin": 333,
"hebei": 444
},
{
"shanxi": 222,
"shandong": 333
}
]
}
- 意思是 china 這個陣列包含兩個陣列,陣列元素又是由 beijing,tianjin,hebei 和 shanxi,shandong 兩個陣列組成
3.3.yaml 多維陣列寫法
- 資料結構的子成員是一個數組,則可以在該項下面縮排一個空格
china:
- beijing:
- changping: 555
- haidian: 777
- shanxi:
- xinzhou: 200
taiyuan: 300 # 同一陣列資料的連字元可以省略
datong:
- hebei:
- cangzhou: 500
xiongan:
-------------------------------
# 轉為 JavaScript 格式
{ china:
[ { beijing: [ { changping: 555 }, { haidian: 777 } ] },
{ shanxi: [ { xinzhou: 200, taiyuan: 300, datong: null } ] },
{ hebei: [ { cangzhou: 500, xiongan: null } ] } ] }
# 轉換為 json 格式
{
"china": [
{
"beijing": [
{
"changping": 555
},
{
"haidian": 777
}
]
},
{
"shanxi": [
{
"xinzhou": 200,
"taiyuan": 300,
"datong": null
}
]
},
{
"hebei": [
{
"cangzhou": 500,
"xiongan": null
}
]
}
]
}
3.4.YAML 複合結構
- 陣列和物件可以結合使用,形成複合結構。
languages: # 值是三個陣列
- Ruby
- Perl
- Python
websites: # 值是三個鍵值對,也就是一個列表或者字典
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org
- 轉為 JavaScript 如下
{ languages: [ 'Ruby', 'Perl', 'Python' ],
websites:
{ YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org' } }
4.YAML 純量
- 純量是最基本的、不可再分的值
字串
布林值
整數
浮點數
Null
時間
日期
- 使用一個例子來快速瞭解純量的基本使用:
boolean:
- TRUE #true,True都可以
- FALSE #false,False都可以
float:
- 3.14
- 6.8523015e+5 #可以使用科學計數法
int:
- 123
- 0b1010_0111_0100_1010_1110 #二進位制表示
null:
nodeName: 'node'
parent: ~ #使用~表示null
string:
- 哈哈
- 'Hello world' #可以使用雙引號或者單引號包裹特殊字元
- newline
newline2 #字串可以拆成多行,每一行會被轉化成一個空格
date:
- 2018-02-17 #日期必須使用ISO 8601格式,即yyyy-MM-dd
datetime:
- 2018-02-17T15:02:31+08:00 #時間使用ISO 8601格式,時間和日期之間使用T連線,最後使用+代表時區
-----------------------------
# 轉換為 JavaScript 格式
{ boolean: [ true, false ],
float: [ 3.14, 685230.15 ],
int: [ 123, 685230 ],
null: { nodeName: 'node', parent: null },
string: [ '哈哈', 'Hello world', 'newline newline2' ],
date: [ Sat Feb 17 2018 08:00:00 GMT+0800 (中國標準時間) ],
datetime: [ Sat Feb 17 2018 15:02:31 GMT+0800 (中國標準時間) ] }
# 轉換為 JSON 格式
{
"boolean": [
true,
false
],
"float": [
3.14,
685230.15
],
"int": [
123,
685230
],
"null": {
"nodeName": "node",
"parent": null
},
"string": [
"哈哈",
"Hello world",
"newline newline2"
],
"date": [
"2018-02-17T00:00:00.000Z"
],
"datetime": [
"2018-02-17T07:02:31.000Z"
]
}
5.YAML 處理字串
5.1.預設字串寫法
- 字串預設可以不加引號
str: 這是一行字串
--------------------------
# 轉為 JavaScript 如下
{ str: '這是一行字串' }
# 轉換為 JSON 格式
{
"str": "這是一行字串"
}
5.2.YAML 處理特殊字元
- 如果字串之中包含空格或特殊字元,需要放在引號之中
str: '內容: 字串'
--------------------------
# 轉為 JavaScript 格式
{ str: '內容: 字串' }
# 轉換為 JSON 格式
{
"str": "內容: 字串"
}
5.3.YAML 處理引號
- 單引號和雙引號都可以使用,雙引號不會對特殊字元轉義。
s1: '內容\n字串'
s2: "內容\n字串"
--------------------------------
# 轉為 JavaScript 格式
{ s1: '內容\\n字串', s2: '內容\n字串' }
# 轉換為 JSON 格式
{
"s1": "內容\\n字串",
"s2": "內容\n字串"
}
- 單引號之中如果還有單引號,必須連續使用兩個單引號轉義。
str: 'labor''s day'
-------------------------
# 轉為 JavaScript 格式
{ str: 'labor\'s day' }
# 轉換為 JSON 格式
{
"str": "labor's day"
}
5.4.YAML處理文字塊(多行字串)
- 字串可以寫成多行,從第二行開始,必須至少有一個空格縮排,換行符會被轉為空格。
str: 這是一段
多行
字串
-----------------------------
# 轉為 JavaScript 格式
{ str: '這是一段 多行 字串' }
# 轉換為 JSON 格式
{
"str": "這是一段 多行 字串"
}
- 多行字串使用 | 可以保留後續的每一個換行符,| 後面不能接資料,需要另起一行寫資料
- 使用 > 標註的文字內容縮排表示的塊,將塊中回車替換為空格,最終連線成一行,大於號 後面可以接資料
- 使用 |- 刪除字串末尾所有的換行標記(刪掉空行)
- 使用 |+ 保留字串末尾的所有換行標記,
s1: | # 保留3個空行,無資料的空行換行標記沒有記錄
Foo
Bar
Noo
s2: > # 保留3個空行,無資料空行的換行標記沒有記錄
Foo
Bar
Noo
s3: |- # 保留3個空行,換行標記只在後面有資料的行上進行保留
Foo
Bar
Noo
s4: |+ # 保留3個空行,記錄了3行空資料的換行標記
Foo
---------------------------------
# 轉為 JavaScript 格式
{ s1: 'Foo\nBar\nNoo\n',
s2: 'Foo Bar Noo\n',
s3: 'Foo\nBar\nNoo',
s4: 'Foo\n\n\n' }
# 轉換為 JSON 格式
{
"s1": "Foo\nBar\nNoo\n",
"s2": "Foo Bar Noo\n",
"s3": "Foo\nBar\nNoo",
"s4": "Foo\n\n\n"
}
6.其他特殊用法
6.1.YAML 引用
- 錨點 & 和別名 *,可以用來引用。
- & 用來建立錨點(defaults_tag),錨點標記後面資料為引用資料
- << 表示合併到當前資料,
-
- 用來引用錨點。
name: &a yaml
book: *a
books:
- java
- *a
- python
# 相當於
name: yaml
book: yaml
books:
- java
- yaml
- python
-----------------------------
# 轉為 JavaScript 格式
{ name: 'yaml',
book: 'yaml',
books: [ 'java', 'yaml', 'python' ] }
# 轉換為 JSON 格式
{
"name": "yaml",
"book": "yaml",
"books": [
"java",
"yaml",
"python"
]
}
- 下面是另一個例子。
- &showell Steve
- Clark
- Brian
- Oren
- *showell
------------------------
# 轉為 JavaScript 格式
[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]
# 轉換為 JSON 格式
[
"Steve",
"Clark",
"Brian",
"Oren",
"Steve"
]
6.2.YAML 轉換資料型別
-
YAML 允許使用兩個感嘆號,可以強制轉換資料型別,
-
單歎號通常是自定義型別,雙歎號是內建型別。
-
內建型別列表:
!!int # 整數型別
!!float # 浮點型別
!!bool # 布林型別
!!str # 字串型別
!!binary # 也是字串型別
!!timestamp # 日期時間型別
!!null # 空值
!!set # 集合
!!omap,!!pairs # 鍵值列表或物件列表
!!seq # 序列,也是列表 !!map # 鍵值表
- 例項演示:
test1: 123 # 值為整數
test2: !!str 456 # 整數轉換為字串
test3: true # true 和 false 預設為布林值
test4: !!bool true # 轉換為布林值,轉換前後一致
test5: !!str true # 轉換為字串
---------------------------------
# 轉為 JavaScript 格式
{ test1: 123,
test2: '456',
test3: true,
test4: true,
test5: 'true' }
# 轉換為 json 格式
{
"test1": 123,
"test2": "456",
"test3": true,
"test4": true,
"test5": "true"
}
6.3.三個句點 ...
- ... 和 --- 配合使用,在一個配置檔案中代表一個檔案的結束:
---
time: 20:03:20
player: Sammy Sosa
action: strike (miss)
...
---
time: 20:03:47
player: Sammy Sosa
action: grand slam
...
6.4.YAML 處理 HTML 標記
- 字串之中可以插入 HTML 標記。
message: |
<p style="color: red">
段落
</p>
----------------------------
# 轉為 JavaScript 格式
{ message: '\n<p style="color: red">\n 段落\n</p>\n' }
# 轉換為 JSON 格式
{
"message": "\n<p style=\"color: red\">\n 段落\n</p>\n"
}
6.5.YAML 對於函式和正則表示式的轉換
- 這是 JS-YAML 庫特有的功能,可以把函式和正則表示式轉為字串。
# example.yml
fn: function () { return 1 }
reg: /test/
解析上面的 yml 檔案的程式碼如下。
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 物件還原到 yaml 檔案的程式碼如下。
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);
}
參考地址:
https://ansible-tran.readthedocs.io/en/latest/docs/YAMLSyntax.html
https://www.ruanyifeng.com/blog/2016/07/yaml.html
https://www.jianshu.com/p/97222440cd08
https://juejin.im/post/6844903743557746702
https://zhuanlan.zhihu.com/p/75067291