YAML语法详细介绍


YAML 是YAML Ain’t Markup Language的缩写, 是一种可读性好、跨语言、基于Unicode 的数据序列化语言。它可以很简单且清晰的表达对象、数组、标量等数据,并通过空白缩进来表达数据的层次结构,非常适合做配置文件,编辑数据结构和文件大纲等。

很多编程语言(如C, Java, Perl, Python, Ruby等)都有其对应的模块包可以处理YAML 语言或YAML 文件(以yml结尾)。 官方文档地址(http://yaml.org/) ,另外网站 (https://onlineyamltools.com/convert-yaml-to-json) 提供了很方便的YAML 转JSON功能,感兴趣的可以在学习时使用。

YAML 语法十分简单,一般遵循以下规则:

  1. 大小写敏感

  2. 使用缩进表示层级关系

  3. 使用空格缩进,不允许使用Tab进行缩进

  4. 缩进的空格数不限制(一般使用两个空格),要求相同层级的元素左对齐

    通常,块缩进的空格数是从第一个非空行中检测到的,任何前导空行包含比第一个非空行更多的空格都会导致错误

  5. 用 ‘#’ 表示注释,几乎可以在任何地方添加注释

YAML 支持三种数据结构:

  1. 对象: 键值对集合,也叫作映射(mapping)/哈希(hash)/字典(dictionary)
  2. 序列:一组按次序排列的值,也叫作数组/列表
  3. 标量: 单一的不可再分的值,包括字符串、数字、值(布尔值或空值)

1. 标量(字符串、数字、值)

标量包含字符串、数字、布尔值、空值、日期

1.1 字符串

字符串是最常见的数据类型,

  • 一般不使用引号,但是下面几种情况需要使用引号:

    1. 字符串中包含以下任一字符时,使用单引号即可,当然可以使用双引号

      !#%@&*`?|><{}[]:,=
      
    2. 字符串以空白符开头或者结尾时

    3. 字符串中包含以下任一控制字符串时,必须使用双引号

      \0, \x01, \x02, \x03, \x04, \x05, \x06, \a,  \b, \t, \n, \v, \f, \r, \x0e, \x0f, \x10,  \x11, \x12, \x13, \x14, \x15, \x16, \x17, \x18,  \x19, \x1a, \e, \x1c, \x1d, \x1e, \x1f, \N,  \_, \L, \P
      
    4. 当字符串看起来是YAML支持的其他标量类型时,需要使用引号,比如 true、false、1、null

    参考示例:

    unicode: "Sosa did fine.\u263A" #包含unicode字符,必须使用双引号
    control: "\b1998\t1999\t2000\n"
    hex esc: "\x0d\x0a is \r\n"
    
    unquoted: Hello
    single: '"Howdy!" he cried.'
    quoted: ' # Not a ''comment''.'
    tie-fighter: '|\-*-/|'
    
    利用python转成json
    {'unicode': 'Sosa did fine.☺', 'control': '\x081998\t1999\t2000\n', 'hex esc': '\r\n is \r\n', 'unquoted': 'Hello', 'single': '"Howdy!" he cried.', 'quoted': " # Not a 'comment'.", 'tie-fighter': '|\\-*-/|'}
    
  • 多行文本时, 用|表示后面的文字,每一行都被视为独立的数据(字符串) ,而>表示只有在遇到空白行或者缩进改变时,才认为是新的数据(字符串) ,注意理解这里说的数据,可以理解为同一句话,即便在文档上看起来是换行了,但还是同一句话,因此换行会被打印成空格,这样能保证在输出的时候,同一句话内没有换行

    name: Mark McGwire
    accomplishment: >
        Mark set a major league
        home run record in 1998.
          home run record in 1998.
    
        hello
    stats: |
        Mark set a major league
        home run record in 1998.
          home run record in 1998.
        hello
    
    利用python转成json
    {'name': 'Mark McGwire', 'accomplishment': 'Mark set a major league home run record in 1998.\n  home run record in 1998.\n\nhello\n', 'stats': 'Mark set a major league\nhome run record in 1998.\n  home run record in 1998.\nhello\n'}
    
  • 使用+保留文字末尾的换行,-表示删除字符串末尾的换行

    name: Mark McGwire
    keep: |+
    
      Mark set a major league
      home run record in 1998.
      hello
    
    
    
    strip: >-
    
      Mark set a major league
      home run record in 1998.
      hello
      
    利用python转成json
    {'name': 'Mark McGwire', 'keep': '\nMark set a major league\nhome run record in 1998.\nhello\n\n\n\n', 'strip': '\nMark set a major league home run record in 1998. hello'}
    
1.2 数字、布尔值、空值、日期
# 整数
canonical: 12345
decimal: +12345
octal: 0o14
hexadecimal: 0xC

# 浮点数
canonical: 1.23015e+3
exponential: 12.3015e+02
fixed: 1230.15
negative infinity: -.inf
not a number: .NaN

#空值
null: [~, null]

# 布尔值
booleans: [true, Yes, ON,FALSE, No, off ]

# 时间
canonical: 2001-12-15T02:59:43.1Z
iso8601: 2001-12-14t21:59:43.10-05:00
spaced: 2001-12-14 21:59:43.10 -5
date: 2002-12-14

python结果
{'canonical': datetime.datetime(2001, 12, 15, 2, 59, 43, 100000, tzinfo=datetime.timezone.utc), 'decimal': 12345, 'octal': '0o14', 'hexadecimal': 12, 'exponential': 1230.15, 'fixed': 1230.15, 'negative infinity': -inf, 'not a number': nan, None: [None, None], 'booleans': [True, True, True, False, False, False], 'iso8601': datetime.datetime(2001, 12, 14, 21, 59, 43, 100000, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=68400))), 'spaced': datetime.datetime(2001, 12, 14, 21, 59, 43, 100000, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=68400))), 'date': datetime.date(2002, 12, 14)}

2. 序列

一组按次序排列的值,有两种表现形式

  • 使用'- ' 表示

    - Mark McGwire
    - Sammy Sosa
    - Ken Griffey
    
    利用python转成list
    ['Mark McGwire', 'Sammy Sosa', 'Ken Griffey']
    
  • 使用[] 表示

    [Mark McGwire, Sammy Sosa, Ken Griffey]
    
    利用python转成list
    ['Mark McGwire', 'Sammy Sosa', 'Ken Griffey']
    

3. 对象

键值对集合,有三种表现形式

  • 使用 key: value, 注意key和value之间是冒号加空格 ': '

    hr:  65    # Home runs
    avg: 0.278 # Batting average
    rbi: 147   # Runs Batted In
    
    利用python转成json
    {'hr': 65, 'avg': 0.278, 'rbi': 147}
    
  • 使用 '? '': '分别表示key和value,使用这中方式可以指定比较复杂的key,如使用序列作为一个key

    ? 
      - Ahri
      - Akali
      - Alistar
    : 
      LOL
    
    对应的json为 (python不支持列表作为字典的key,因此报错,这里没有拷贝python的转换结果)
    {['Ahri','Akali','Alistar']:'LOL'}
    
  • 使用 {}表示

    {hr: 65, avg: 0.278, rbi: 147}
    
    利用python转成json
    {'hr': 65, 'avg': 0.278, 'rbi': 147}  
    

4. 其他数据类型

4.1 有序集合
# Ordered maps are represented as
# A sequence of mappings, with
# each mapping having one key
--- !!omap
- Mark McGwire: 65
- Sammy Sosa: 63
- Ken Griffy: 58

利用python转成json
[('Mark McGwire', 65), ('Sammy Sosa', 63), ('Ken Griffy', 58)]
4.2 无序集合
# Sets are represented as a
# Mapping where each key is
# associated with a null value
--- !!set
? Mark McGwire
? Sammy Sosa
? Ken Griff

利用python转成json
{'Sammy Sosa', 'Ken Griff', 'Mark McGwire'}
4.3 二进制类型
# 值奖杯解析为以base64编码的二进制值

picture: !!binary |
    R0lGODlhDAAMAIQAAP//9/X
    17unp5WZmZgAAAOfn515eXv
    Pz7Y6OjuDg4J+fn5OTk6enp
    56enmleECcgggoBADs=

5. 强制类型转换

使用双叹号!! 表示内置数据类型的强制数据转换,单叹号!通常表示自定义类型的数据转换。

!!int # 整数类型 
!!float # 浮点类型 
!!bool # 布尔类型 
!!str # 字符串类型 
!!binary # 二进制类型
!!timestamp # 日期时间类型 
!!null # 空值 
!!set # 集合 
!!omap,!!pairs # 键值列表或对象列表
!!seq # 序列,也是列表 !!map # 键值表

6. 文档标识符

使用 --- 表示文档开头,... 表示文档结尾, 文档可理解为同一个yaml文件的不同的数据

---
time: 20:03:20
player: Sammy Sosa
action: strike (miss)
...
---
time: 20:03:47
player: Sammy Sosa
action: grand slam
...


利用python转成json ,会返回两个数据结构(该例子中均为字典)
{'time': 72200, 'player': 'Sammy Sosa', 'action': 'strike (miss)'}
{'time': 72227, 'player': 'Sammy Sosa', 'action': 'grand slam'}

7. 锚点使用

&用来创建锚点,* 用来引用锚点,<<表示合并到当前数据

---
hr:
  - Mark McGwire
  # Following node labeled SS
  - &SS Sammy Sosa
rbi:
  - *SS # Subsequent occurrence
  - Ken Griffey

--- 
move1: &move
  time: 20:03:47
  player: Sammy Sosa
  action: grand slam

detail: 
  stars: 80
  type: love
  <<: *move

利用python转成json   

{'hr': ['Mark McGwire', 'Sammy Sosa'], 'rbi': ['Sammy Sosa', 'Ken Griffey']} 

{'move1': {'time': 72227, 'player': 'Sammy Sosa', 'action': 'grand slam'}, 'detail': {'time': 72227, 'player': 'Sammy Sosa', 'action': 'grand slam', 'stars': 80, 'type': 'love'}}

8. 完整例子

发票

--- 
invoice: 34843
date   : 2001-01-23
bill-to: &id001
    given  : Chris
    family : Dumars
    address:
        lines: |
            458 Walkman Dr.
            Suite #292
        city    : Royal Oak
        state   : MI
        postal  : 48046
ship-to: *id001
product:
    - sku         : BL394D
      quantity    : 4
      description : Basketball
      price       : 450.00
    - sku         : BL4438H
      quantity    : 1
      description : Super Hoop
      price       : 2392.00
tax  : 251.42
total: 4443.52
comments:
    Late afternoon is best.
    Backup contact is Nancy
    Billsmer @ 338-4338.
    
利用python转成json    
{'invoice': 34843, 'date': datetime.date(2001, 1, 23), 'bill-to': {'given': 'Chris', 'family': 'Dumars', 'address': {'lines': '458 Walkman Dr.\nSuite #292\n', 'city': 'Royal Oak', 'state': 'MI', 'postal': 48046}}, 'ship-to': {'given': 'Chris', 'family': 'Dumars', 'address': {'lines': '458 Walkman Dr.\nSuite #292\n', 'city': 'Royal Oak', 'state': 'MI', 'postal': 48046}}, 'product': [{'sku': 'BL394D', 'quantity': 4, 'description': 'Basketball', 'price': 450.0}, {'sku': 'BL4438H', 'quantity': 1, 'description': 'Super Hoop', 'price': 2392.0}], 'tax': 251.42, 'total': 4443.52, 'comments': 'Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.'}

日志文件

---
Time: 2001-11-23 15:01:42 -5
User: ed
Warning:
  This is an error message
  for the log file
---
Time: 2001-11-23 15:02:31 -5
User: ed
Warning:
  A slightly different error
  message.
---
Date: 2001-11-23 15:03:17 -5
User: ed
Fatal:
  Unknown variable "bar"
Stack:
  - file: TopClass.py
    line: 23
    code: |
      x = MoreObject("345\n")
  - file: MoreClass.py
    line: 58
    code: |-
      foo = bar
      
      
      
{'Time': datetime.datetime(2001, 11, 23, 15, 1, 42, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=68400))), 'User': 'ed', 'Warning': 'This is an error message for the log file'}

{'Time': datetime.datetime(2001, 11, 23, 15, 2, 31, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=68400))), 'User': 'ed', 'Warning': 'A slightly different error message.'} 

{'Date': datetime.datetime(2001, 11, 23, 15, 3, 17, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=68400))), 'User': 'ed', 'Fatal': 'Unknown variable "bar"', 'Stack': [{'file': 'TopClass.py', 'line': 23, 'code': 'x = MoreObject("345\\n")\n'}, {'file': 'MoreClass.py', 'line': 58, 'code': 'foo = bar'}]}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积跬步以至千里。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值