将YAML多行值转换为折叠块标量样式?

2024-09-30 20:22:44 发布

您现在位置:Python中文网/ 问答频道 /正文

使用ruamel.yaml我试图获得某种样式的YAML,更具体地说,单行字符串与:在同一行开始,多行字符串使用折叠标量样式(|/|-),行数限制为一定数量的字符(单词换行)。在

到目前为止,我的尝试深受similar function called ^{} in the sources的影响: 在

#!/usr/bin/env python

import ruamel.yaml

from ruamel.yaml.scalarstring import ScalarString, PreservedScalarString

def walk_tree(base):
    from ruamel.yaml.compat import string_types

    if isinstance(base, dict):
        for k in base:
            v = base[k]
            if isinstance(v, string_types):
                v = v.replace('\r\n', '\n').replace('\r', '\n').strip()
                base[k] = ScalarString(v) if '\n' in v else v
            else:
                walk_tree(v)
    elif isinstance(base, list):
        for idx, elem in enumerate(base):
            if isinstance(elem, string_types) and '\n' in elem:
                print(elem) # @Anthon: this print is in the original code as well
                base[idx] = preserve_literal(elem)
            else:
                walk_tree(elem)

with open("input.yaml", "r") as fi:
    inp = fi.read()

loader=ruamel.yaml.RoundTripLoader
data = ruamel.yaml.load(inp, loader)

walk_tree(data)

dumper = ruamel.yaml.RoundTripDumper

with open("output.yaml", "w") as fo:
    ruamel.yaml.dump(data, fo, Dumper=dumper, allow_unicode=True)

但是我得到了一个异常:ruamel.yaml.representer.RepresenterError: cannot represent an object: …。如果我把ScalarString替换为PreservedScalarString,就像原来的walk_tree代码一样,我也没有例外,但是我又得到了不是我想要的文本块。在

那么,如何修复我的代码,使其正常工作呢?在


Tags: inimporttreeyamlbasestringifas
1条回答
网友
1楼 · 发布于 2024-09-30 20:22:44

ScalarStringLiteralScalarString的基类,正如您所发现的,它没有representer。您应该将它作为一个Python字符串,因为它适当地处理特殊字符(引用需要引用的字符串以符合YAML规范)。在

假设您有这样的输入:

- 1
- abc: |
    this is a short string scalar with a newline
    in it
- "there are also a multiline\nsequence element\nin this file\nand it is longer"

你可能想做些类似的事情:

^{pr2}$

要获得输出:

^{3}$

注意事项:

  • 使用LiteralScalarString优于PreservedScalarString。后者称之为当时唯一保留下来的字符串类型的残余。在
  • 您可能没有序列元素来存放字符串,因为您没有导入preserve_literal,尽管它仍然在复制的代码中使用。在
  • 我把“换行”代码分解成test_wrap,由value和element包装使用,最大行长度设置为72个字符。在
  • data[1]['abc']作为LiteralScalarString加载。如果您想保留现有的文字样式字符串标量,您应该在测试string_types类型之前测试这些标量。在
  • 我将新的API与YAML()的实例一起使用
  • 如果将示例中的72增加到默认值80以上,则可能必须将width属性设置为1000之类的值,以防止自动换行。(yaml.width = 1000

相关问题 更多 >