YAML语法

YAML 语法

0.在线工具:yaml 校验工具

  • yaml 转 JS

http://nodeca.github.io/js-yaml/

  • yaml 转 json(格式互转)

http://www.bejson.com/json/json2yaml/

  • yaml 在线编辑

https://www.bejson.com/validators/yaml_editor/

  • json 格式转换

https://www.json.cn/

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 库特有的功能,可以把函数和正则表达式转为字符串。

https://github.com/nodeca/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

posted @ 2020-08-24 17:57  天生帅才  阅读(3794)  评论(0编辑  收藏  举报
// 百度统计