TOML语法规范

前言:

不能多次定义键和表格

表格数组里面的内容常用(重要点)。表格数组中,一对[]表示对象,[[]]双方括号表示数组对象


TOML

全称:Tom’s Obvious, Minimal Language

作者:Tom Preston-Werner

最新版本:v0.4.0

注意,这个规范还持续变动中,因此你必须时刻都假定着它是一个不稳定的规范并对此做出一些防范措施直到它正式发布了 1.0 版。

目标

TOML 的目标是成为一个拥有明显语义且容易阅读的最小化的配置文件格式。TOML 被设计成可以无歧义地被映射为哈希表,从而可以很容易地被解析成各种语言中的数据结构。

例子

# 这是一个 TOML 的文档。

title ="TOML 例子"

[owner]

name ="Tom Preston-Werner"

dob =1979-05-27T07:32:00-08:00# 日期是一等公民

[database]

server ="192.168.1.1"

ports = [8001,8001,8002]

connection_max =5000

enabled =true

[servers]

# 缩进(制表符和(或)空格)是允许的,但不是必需的

[servers.alpha]

ip ="10.0.0.1"

dc ="eqdc10"

[servers.beta]

ip ="10.0.0.2"

dc ="eqdc10"

[clients]

data = [ ["gamma","delta"], [1,2] ]

# 在数组内部换行是允许的

hosts = [

"alpha",

"omega"

]

规范

TOML 文档是大小写敏感的。

TOML 文档必须是一个有效的UTF-8编码的Unicode文档。

空白符只能是制表符(0x09)或空格(0x20)。

换行符只能是 LF(0x0A)或 CRLF (0x0D0A)。

注释

#将该行的其余部分标记为注释。

# 这是一个占据整行的注释

key="value"# 这是一个在行末的注释

键值对

一个 TOML 文档的主要构建块是键值对

在=的左边,在右边。周围的空白符忽略不计。、=和必须位于同一行(虽然一些可以被折成多行)。

key="value"

可以是裸露的裸键,也可以是被包裹在一对"的内部的引用键裸键只能存在字母、数字、下划线和破折号(a-zA-Z0-9_-)。注意,裸键可以只由数字组成,例如1234,但它总是被解析为字符串。引用键遵循与基本字符串字面字符串完全相同的规范,并允许使用更广泛的键名称。最好的做法是使用裸键,除非必要情况。

key ="value"

bare_key ="value"

bare-key ="value"

1234="value"

"127.0.0.1"="value"

"character encoding"="value"

"ʎǝʞ"="value"

'key2'="value"

'quoted "value"'="value"

裸键不允许为空,但引用键允许(虽然这会导致不可见)。

="no key name"# 非法

""="blank"# 合法但不可见

''='blank'# 合法但不可见

可以是以下类型:字符串整数浮点数布尔值时间数组内联表。未确定的值是非法的。

key=# 非法

字符串

字符串的表示方法有四种:基本字符串多行基本字符串字面字符串多行字面字符串。所有字符串都必须只包含有效的UTF-8字符。

基本字符串被包裹在一对"的内部。任何的Unicode字符都可以直接使用,除了那些必须被转义的字符:",\和控制字符(U+0000到U+001F)。

str ="I'm a string. \"You can quoteme\". Name\tJos\u00E9\nLocation\tSF."

为了方便起见,一些流行的字符都有简短的转义序列。

\b        - 退格键  (U+0008)

\t        - 制表符  (U+0009)

\n        - 换行符  (U+000A)

\f        - 换页符  (U+000C)

\r        - 回车符  (U+000D)

\"        - "(U+0022)

\\        - \      (U+005C)

\uXXXX    -Unicode(U+XXXX)

\UXXXXXXXX -Unicode(U+XXXXXXXX)

任何的Unicode字符都可以通过\uXXXX或\UXXXXXXXX形式转义。转义的编码必须是有效的标量值

所有上面未列出的其他的转义序列都将被保留不能使用,如果使用,则必须在解析时抛出一个错误。

有些时候可能需要表示文本的段落(例如:翻译文件)或想要将一个非常长的字符串折成多行。TOML 完成起来非常容易。多行基本字符串被包裹在有限行两侧的一对"""的内部。新行起始位置的换行符将会被忽略不计。所有其他的空白符和换行符都将被保留下来。

str1 ="""

Roses are red

Violets are blue"""

TOML 解析器必须兼容不同平台的换行符。

# 在 Unix 系统上,上面的多行字符串必须和这个一样:

str2 ="Roses are red\nViolets are blue"

# 在 Windows 系统上,必须和这个一样:

str3 ="Roses are red\r\nViolets are blue"

书写长字符串时,使用行结束符来避免引入多余的空白符。当行末的字符是\时,TOML 将会忽略所有的空白符(包括换行符)直到遇到非空白符或"""。所有对于基本字符串有效的转义序列对于多行基本字符串也是有效的。

# 以下字符串完全相同:

str1 ="The quick brown fox jumps over the lazy dog."

str2 ="""

The quick brown \

  fox jumps over \

    the lazy dog."""

str3 ="""\

      The quick brown \

      fox jumps over \

      the lazy dog.\

      """

任何的Unicode字符都可以直接使用,除了那些必须被转义的字符:\和控制字符(U+0000到U+001F)。"不需要转义,除非它的存在会导致多行字符串过早结束。

TOML 还支持不含任何转义的字面字符串字面字符串被包裹在一对'的内部,像基本字符串一样,它们必须位于同一行。

# 所见即所得。

winpath  ='C:\Users\nodejs\templates'

winpath2 ='\\ServerX\admin$\system32\'

quoted  ='Tom "Dubs" Preston-Werner'

regex    ='<\i\c*\s*>'

由于不含转义,也就没法在字面字符串内书写'了。但幸运的是,TOML 还支持了可以很好的解决这个问题的多行字面字符串多行字面字符串被包裹在有限行两侧的一对'''的内部。像字面字符串一样,多行字面字符串不含任何转义。新行起始位置的换行符将会被忽略不计。所有其他的字符都将被完整地保留下来。

regex2 ='''I [dw]on't need \d{2} apples'''

lines  ='''

The first newline is

trimmed in raw strings.

  All other whitespace

  is preserved.

'''

对于二进制数据,建议使用Base64或其它合适的ASCII或UTF-8编码。编码的处理将是特定于应用程序的。

整数

整数分为正数负数正数前的+不是必须的,但负数前必须存在-。

int1 = +99

int2 = 42

int3 = 0

int4 = -17

对于较大的数字,可以使用_来增强其可读性。_必须被数字包围。

int5 =1_000

int6 =5_349_221

int7 =1_2_3_4_5# 合法但不可见

前导零、十六进制、八进制和二进制都是不允许的。像是“infinity”和“not a number”这种不能表示为一个连续的数字序列的值也是不被允许的。

整数是 64 位的长整型,范围是:−9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。

浮点数

浮点数整数部分(与整数相同的规范)和小数部分和(或)指数部分组成。如果小数部分指数部分同时存在,那么小数部分必须先于指数部分

# 小数

flt1 = +1.0

flt2 =3.1415

flt3 =-0.01

# 指数

flt4 =5e+22

flt5 =1e6

flt6 =-2E-2

# 二者

flt7 =6.626e-34

小数部分由一个.开始,然后是一个或多个数字组成。

指数部分由一个E(大小写均可)开始,然后是一个整数部分(和整数遵循相同的规范)组成。

整数类似,浮点数可以使用_来增强其可读性。_必须被数字包围。

flt8 = 9_224_617.445_991_228_313

浮点数是 64 位的(双)精度数。

布尔值

布尔值的用法和在其他语言中的一样,且必须小写。

bool1 =true

bool2 =false

偏移日期时间

为了明确地表示特定的日期时间,可以使用RFC 3339来格式化日期时间的偏移量。

odt1 = 1979-05-27T07:32:00Z

odt2 = 1979-05-27T00:32:00-07:00

odt3 = 1979-05-27T00:32:00.999999-07:00

秒的小数部分的精度至少是毫秒级。如果值的精度远比实现的要高,那么多余的精度必须被截断,而不是舍入。

本地日期时间

如果省略RFC 3339格式的日期时间的偏移量,那么它将只表示给定的日期时间且与偏移量和时区没有任何关系。如果没有附加信息,那么它不能被转换成即时时间。如果需要转换为即时时间,则取决于具体的实现。

ldt1 = 1979-05-27T07:32:00

ldt2 = 1979-05-27T00:32:00.999999

秒的小数部分的精度至少是毫秒级。如果值的精度远比实现的要高,那么多余的精度必须被截断,而不是舍入。

本地日期

如果只包括RFC 3339格式的日期时间的日期部分,那么它将只表示给定的日期且与偏移量和时区没有任何关系。

ld1 = 1979-05-27

本地时间

如果只包括RFC 3339格式的日期时间的时间部分,那么它将只表示给定的时间且与偏移量和时区没有任何关系。

lt1 = 07:32:00

lt2 = 00:32:00.999999

秒的小数部分的精度至少是毫秒级。如果值的精度远比实现的要高,那么多余的精度必须被截断,而不是舍入。

数组

数组被包裹在[和]的内部。空白符忽略不计。元素由,分隔。不能混用数据类型(字符串的不同实现被认为是同一种数据类型,因此必须使用不同类型的数组)。

arr1 = [1,2,3]

arr2 = ["red","yellow","green"]

arr3 = [ [1,2], [3,4,5] ]

arr4 = ["all",'strings',"""are the same""",'''type''']

arr5 = [ [1,2], ["a","b","c"] ]

arr6 = [1,2.0]# 非法

数组还可以被折成多行。所以除了空白符,数组还忽略了[和]的内部的换行符和注释。]前允许出现,。

arr7 = [

1,2,3

]

arr8 = [

1,

2,# 这是允许的

]

表格

表格(也叫哈希表字典)是一个键值对的集合。它们被包裹在[和]的内部且自成一行。表格数组是不同的,因为数组只有值。

[table]

在此之下,直到下一个表格EOF之前,都是该表格键值对表格中的键值对是无序的。

[table-1]

key1 ="some string"

key2 =123

[table-2]

key1 ="another string"

key2 =456

.禁止出现在裸键内,因为.是用来表示嵌套表的。每个.分隔的部分的命名规范与相同。

[dog."tater.man"]

type="pug"

转换成JSON结构如下:

{"dog": {"tater.man": {"type":"pug"} } }

.周围的空白符忽略不计,建议不要使用多余的空白符。

[a.b.c]# 这样做最好

[ d.e.f ]# 等价于 [d.e.f]

[ g .  h  . i ]# 等价于 [g.h.i]

[j ."ʞ". 'l']# 等价于 [j."ʞ".'l']

如果不想的话,可以不用声明所有的父表。TOML 知道该如何处理。

# [x] 你

# [x.y] 不需要

# [x.y.z] 这样

[x.y.z.w]# 直接这样就行

空表是允许的,其中没有键值对

只要父表没有被直接定义,而且没有定义一个特定的,可以继续写入:

[a.b]

c =1

[a]

d =2

不能多次定义表格。这么做是不合法的。

# 别这么干!

[a]

b =1

[a]

c =2

# 也别这么干!

[a]

b =1

[a.b]

c =2

表格的名称必须是非空的。

[]# 非法

[a.]# 非法

[a..b]# 非法

[.b]# 非法

[.]# 非法

内联表

内联表提供了更紧凑语法来表示表格。它们对于分组数据特别有用,否则将很快变得冗长。内联表被包裹在{和}的内部。在{和}的内部,可能会出现零个或多个用,分隔的键值对键值对标准表中的键值对形式相同。允许所有的值类型,包括内联表

内联表的目的是出现在单行。{和}内不允许出现换行符,除非它存在于一个内。即便如此,还是强烈建议不要将一个内联表折成多行。如果你发现自己被这种欲望所困扰,那意味着你应该使用标准表

name = { first ="Tom",last="Preston-Werner"}

point = {x=1,y=2}

上面的内联表与下面的标准表完全相同:

[name]

first ="Tom"

last ="Preston-Werner"

[point]

x =1

y =2

表格数组

最后要介绍的类型是表格数组表格数组可以通过包裹在[[和]]内的表格名来表达。使用相同的双方括号名称的表格是同一个数组的元素。表格按照书写的顺序插入。双方括号表格如果没有键值对,会被当成空表

[[products]]

name ="Hammer"

sku =738594937

[[products]]

[[products]]

name ="Nail"

sku =284758393

color ="gray"

转换成JSON结构如下:

{

"products": [

{"name":"Hammer","sku":738594937},

    { },

{"name":"Nail","sku":284758393,"color":"gray"}

  ]

}

表格数组同样可以嵌套。只需在子表上使用相同的双方括号语法。每一个双方括号子表会从属于最近定义的上层表格元素。

[[fruit]]

name ="apple"

[fruit.physical]

color ="red"

shape ="round"

[[fruit.variety]]

name ="red delicious"

[[fruit.variety]]

name ="granny smith"

[[fruit]]

name ="banana"

[[fruit.variety]]

name ="plantain"

转换成JSON结构如下:

{

"fruit": [

    {

"name":"apple",

"physical": {

"color":"red",

"shape":"round"

      },

"variety": [

{"name":"red delicious"},

{"name":"granny smith"}

      ]

    },

    {

"name":"banana",

"variety": [

{"name":"plantain"}

      ]

    }

  ]

}

试图追加到静态定义的数组中,即使该数组为空或兼容类型,也必须在解析时抛出错误。

# 非法的 TOML 文档

fruit = []

[[fruit]]# 不允许

试图定义一个标准表,且使用已经定义的数组的名称,则必须在解析时抛出错误:

# 非法的 TOML 文档

[[fruit]]

name ="apple"

[[fruit.variety]]

name ="red delicious"

# 这个表格和上面的冲突了

[fruit.variety]

name ="granny smith"

也可以在适当的时候使用内联表

points = [ { x = 1, y = 2, z = 3 },

          { x = 7, y = 8, z = 9 },

          { x = 2, y = 4, z = 8 } ]

文件扩展名

TOML 文件必须使用.toml来作为其扩展名

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容