
PyYAML 的 yaml.safe_load() 默认会折叠多行字符串中的多余空白(包括缩进空格),导致换行后缩进丢失;使用 YAML 字面量块标量(|-)可完整保留原始换行与空格。
pyyaml 的 `yaml.safe_load()` 默认会折叠多行字符串中的多余空白(包括缩进空格),导致换行后缩进丢失;使用 yaml 字面量块标量(`|-`)可完整保留原始换行与空格。
在 PyYAML 中处理含换行和缩进的字符串时,需特别注意 YAML 的多行字符串风格规则。默认情况下,safe_load() 将未显式指定样式的多行字符串解析为“折叠块标量”(>),其语义是:自动将换行符归一化为单个空格,并删除行首缩进——这正是问题中 'first\n\n second' 被解析为 'first\nsecond' 的根本原因(中间空行被压缩,第二行前的 9 个空格被丢弃)。
要精确保留原始换行符与每行的前导空格,必须显式使用 字面量块标量(Literal Block Scalar),语法以 |- 开头(| 表示保留换行,- 表示去除末尾单个换行)。正确写法如下:
import yaml
# ✅ 正确:使用 |- 显式声明字面量块标量
data = yaml.safe_load("|-\n first\n second")
print(repr(data))
# 输出: 'first\n second'
⚠️ 注意事项:
- |- 后必须紧跟换行符,随后的每一行内容(包括空行和缩进行)都会原样保留;
- 首行缩进(即 |- 所在行与内容行之间的缩进)会被 YAML 解析器忽略,但内容行自身的缩进(如 second 前的 9 个空格)会被完整保留;
- 若字符串来自变量或模板,需确保生成的 YAML 字符串符合字面量语法(例如通过 f-string 或 textwrap.dedent 配合手动添加 |-);
- 避免混用 |(保留末尾换行)与 |-(删除末尾换行)导致意外的尾部空行。
总结:当需要保真还原带缩进的多行文本(如配置片段、SQL 查询、代码示例等)时,永远优先选用 |- 字面量风格,而非依赖默认解析行为。这是 YAML 规范设计的明确机制,也是 PyYAML 完全支持的标准实践。











