- 1. 为什么需要多行块?
- 2. 字面块 (Literal Block) -
|
- 3. 折叠块 (Folded Block) -
>
- 4. 关键区别总结 (
|
vs>
) - 5. 共同规则与注意事项
- 6. 如何选择?(
|
vs>
) - 7. 高级技巧
YAML 因其简洁性和可读性,成为配置文件、数据序列化的热门选择。当需要处理包含换行符的长字符串(如段落文本、代码片段、日志信息等)时,YAML 提供了两种强大的标量块样式:字面块 (|
) 和 折叠块 (>
)。它们允许你以更自然、易读的方式在 YAML 文件中编写多行文本。
1. 为什么需要多行块?
直接在 YAML 值中使用换行符通常会导致语法错误或解析困难。例如:
# 错误示例:直接换行不被允许(除非在引号内,但引号内换行处理复杂)
description: 这是第一行
这是第二行 # 语法错误!
使用双引号 "
或单引号 '
虽然可以包含换行符,但需要转义特殊字符(双引号内),并且处理内部引号和长文本时易读性较差:
# 使用双引号(可包含换行,但需要转义内部双引号和反斜杠,阅读困难)
description: "这是第一行。\n这是第二行,包含一个\"引号\"。\n第三行。"
|
和 >
解决了这些问题,它们:
- 提高可读性: 多行文本以其自然格式嵌入 YAML 文件。
- 简化书写: 无需使用
\n
显式表示换行。 - 保留或控制空白: 根据需要保留原始换行或将其折叠成空格。
2. 字面块 (Literal Block) - |
- 符号: 使用竖线
|
后跟换行符开始。 - 核心行为: 严格保留 输入文本中的所有换行符和行尾的空白。文本块内的缩进和行首空白也会被保留。
- 结果: 解析后的字符串将包含你在 YAML 块中编写的所有换行符,格式与你在文件中看到的几乎完全一致。
- 适用场景:
- 需要精确保留格式的文本:代码片段、配置文件片段、ASCII 艺术、预格式化文本(如 Markdown/HTML 源码)。
- 需要保留每一行末尾空白的文本(虽然不常见)。
- 日志信息、错误消息等需要原样输出的多行文本。
- 示例:
code_snippet: |
def hello_world():
print("Hello, World!")
# 这是一个注释
if True:
print("YAML blocks are useful!")
# 解析后的值(Python 示例):
# "def hello_world():\n print(\"Hello, World!\")\n # 这是一个注释\n if True:\n print(\"YAML blocks are useful!\")\n"
# 注意:保留了所有缩进、换行和行尾的注释。
3. 折叠块 (Folded Block) - >
- 符号: 使用右尖括号
>
后跟换行符开始。 - 核心行为: 将文本块中的换行符替换为空格。但是,有一些重要的规则和例外:
- 折叠规则: 连续的、非空行会被折叠成一个空格分隔的长行。
- 保留空行: 空行(即完全没有任何字符,包括空格的行)会被保留,并作为换行符输出。空行是重要的分隔符。
- 行尾反斜杠
\
: 如果一行以非转义的反斜杠\
结尾,则该行不会折叠到下一行(即该换行符被保留),并且反斜杠会被移除(除非它被转义\\
)。 - 行首空白: 块内的缩进和行首空白会被保留(与
|
相同)。
- 结果: 解析后的字符串是一个“折叠”的文本段落。原本独立的非空行被合并成用空格连接的单行,但空行和以
\
结尾的行会创建新的行。 - 适用场景:
- 长段落文本:如描述、文档、消息正文等,其中换行是为了文件可读性,但在实际使用中应作为连续文本(可能由空格分隔)。
- 希望大部分内容为单行,但需要保留段落分隔(通过空行)。
- 需要精确控制某些换行位置(通过行尾
\
)。
- 示例:
description: >
This is the first sentence of a paragraph.
This is the second sentence, which will be joined
to the first with a space. It's much easier to read
in the YAML file this way.
This is a new paragraph because there was an empty
line above. It will be separated by a newline.
This line ends with a single backslash \
so the next line starts on a new line. The backslash is removed.
# 解析后的值(Python 示例):
# "This is the first sentence of a paragraph. This is the second sentence, which will be joined to the first with a space. It's much easier to read in the YAML file this way.\n\nThis is a new paragraph because there was an empty line above. It will be separated by a newline.\nThis line ends with a single backslash so the next line starts on a new line. The backslash is removed.\n"
# 注意:
# - 第一段的所有非空行被折叠成一个长句(空格连接)。
# - 两个空行(在YAML块中)变成了两个换行符 `\n\n`,分隔段落。
# - 以 `\` 结尾的行:反斜杠被移除,该行与下一行之间的换行符被保留(即 `\n` 出现在 `backslash` 和 `so` 之间)。
4. 关键区别总结 (|
vs >
)
特性 | |(字面量块) | >(折叠块) |
---|---|---|
换行保留 | 保留所有换行 | 将换行转换为空格(除非是空行) |
最终结果 | 多行字符串(带换行) | 单行或段落式字符串(带空格) |
适合内容 | 脚本、配置段、代码块 | 描述文字、段落性说明文本 |
阅读体验 | 更易于阅读格式化内容 | 更紧凑,节省行数 |
尾部换行控制 | 支持 |-, |+ | 支持 >-, >+ |
空行处理 | 原样保留 | 保留段落(空行)分隔 |
5. 共同规则与注意事项
- 缩进 (Indentation):
- 块内容必须相对于块指示符 (
|
或>
) 统一缩进。这个缩进级别定义了“块内容的起始列”。 - YAML 解析器会剥离这个公共缩进前缀。块内容中每一行开头的、与公共缩进级别相同的空格会被移除。
- 公共缩进级别之后的缩进(即块内容内部的额外缩进)会被保留。
- 重要: 块内所有行的缩进必须大于或等于块指示符的缩进级别。否则会导致解析错误。
- 块内容必须相对于块指示符 (
- 块结尾与尾随换行符:
- 块由一个缩进级别小于块内容起始缩进级别的行结束,或者由文档结束结束。
- 默认情况下,YAML 解析器会在解析后的字符串末尾添加一个换行符 (
\n
)。这是符合 POSIX 标准的常见行为(文本文件以换行符结尾)。 - 可以使用块指示符修饰符控制这个行为:
|
或>
:默认行为,保留块末尾的换行符(即添加一个\n
)。|-
或>-
:剥离 (strip) 块末尾的换行符。解析后的字符串不包含最后一个换行符。|+
或>+
:保留 (keep) 块末尾的所有换行符。如果块结束时有多行空行,它们都会被保留。 * 示例: ```yaml with_newline: | # 默认,等价于 | 或 > Line 1 Line 2注意这里下面还有一个空行
stripped: |- Line 1 Line 2
kept: |+ Line 1 Line 2
解析结果:
with_newline: “Line 1\nLine 2\n\n” (末尾有1个换行符,来自最后那个空行,再加上默认添加的一个?注意:规范是块内容结束行后的空行也会影响,具体实现可能略有差异,通常
|
会保留内容中所有行包括末尾空行)stripped: “Line 1\nLine 2” (无末尾换行符)
kept: “Line 1\nLine 2\n\n” (保留了内容末尾的两个换行符)
```
- 关于尾随换行符的具体处理,YAML 规范有详细定义,不同解析器实现可能稍有差异,但
-
和+
的意图是明确的。最安全的做法是明确使用-
或+
来表达你的需求。
- 空格与制表符: YAML 通常推荐使用空格进行缩进。虽然规范允许制表符 (
\t
),但强烈建议避免使用制表符,因为不同环境对制表符宽度的解释不同,极易导致缩进错误和解析问题。坚持使用空格(通常是 2 个或 4 个)是最佳实践。 - 转义字符: 在
|
和>
块内,大多数字符都是字面量,不需要转义。双引号"
、单引号'
、反斜杠\
等都可以直接书写(除了在折叠块>
中行尾的\
有特殊含义)。这使得包含这些字符的文本(如 HTML、SQL)写起来非常方便。例如,在|
块中写"This is a quote"
完全没问题。 - 与引号标量的对比:
|
和>
提供了比双引号"
或单引号'
更清晰、更适合处理真正多行且需要控制空白的文本的方式。引号标量更适合单行字符串或在单行内需要转义/处理特殊字符的场景。
6. 如何选择?(|
vs >
)
- 选择
|
(字面块) 当:- 你需要完全保留原始格式、所有换行符和行尾空白。
- 内容本质上是代码、结构化文本或预格式化内容。
- 换行符具有语义意义(例如,每行代表一个列表项、一个命令、一个日志条目)。
- 选择
>
(折叠块) 当:- 你的内容是自然语言段落。
- 文件中的换行主要是为了提高 YAML 文件自身的可读性,你希望这些换行在解析后变成空格(使文本更连贯)。
- 你仍然需要通过空行来表示段落分隔。
- 你需要偶尔精确控制某个换行位置(使用行尾
\
)。
7. 高级技巧
- 结合使用: 一个 YAML 文档中可以自由混合使用
|
和>
块,以及其他标量样式(普通、单引号、双引号)。 - 嵌套结构: 块标量可以嵌套在映射(键值对)的值中或序列(列表)的项中。
- 明确意图: 总是使用
-
或+
修饰符来明确你对尾随换行符的期望 (|
,|-
,|+
,>
,>-
,>+
),避免歧义。
YAML 的 |
(字面块) 和 >
(折叠块) 是处理多行字符串的强大工具,它们显著提升了配置文件和复杂数据结构的可读性和可维护性。理解它们之间的核心区别——|
严格保留换行,>
折叠换行为空格(但保留空行和 \
行)——以及缩进、尾随换行控制等共同规则,是有效使用 YAML 的关键。根据你的文本内容是强调精确格式还是自然语言流,明智地选择 |
或 >
,能让你的 YAML 文件既整洁又准确地表达意图。

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
腾讯云开发者社区:孟斯特
—