使用ruamel.yaml使用相同的缩进Python保留多行字符串

时间:2018-06-29 14:00:25

标签: yaml ruamel.yaml

我正在尝试组成一些YAML文件,并且正在努力以正确的格式获取YAML文件。我试图使所有值的字符串都使用相同的缩进,但似乎无法正常工作。

ResourceIndicators:
  version: 1.0.0
  name: This is the name
  neType: Text
  category: Text
  description: The is the first line of the sentence and then we continue 
    on to the second line but this line should be indented to match the 
    first line of the string. 

这是我所拥有的,但我正在寻找:

ResourceIndicators:
  version: 1.0.0
  name: This is the name
  neType: Text
  category: Text
  description: The is the first line of the sentence and then we continue 
               on to the second line but this line should be indented to 
               match the first line of the string. 

1 个答案:

答案 0 :(得分:0)

ruamel.yaml(或PyYAML)中没有选择或简单的方法来获取所需的内容。

description映射键的值是普通标量,您可能已将输出宽度设置为70(或类似值)以得到该结果。该值是普通样式的标量,可以在由非空格字符包围的任何空格上破坏。

您可能已经考虑过使用块样式的文字标量,但是

  description: |-
               The is the first line of the sentence and then we continue
               on to the second line but this line should be indented to match the
               first line of the string.

几乎看起来很相似,它实际上在该字符串中加载了两个额外的换行符。 即使您在转储前对该标量进行预处理,并在加载后对其进行后处理以尝试使用显式块缩进指示器,也不会给您提供超过9个位置(因为它仅限于一个数字),并且您拥有的位置也更多。

如果可接受以下格式:

ResourceIndicators:
  version: 1.0.0
  name: This is the name
  neType: Text
  category: Text
  description: |-
    The is the first line of the sentence and then we continue
    on to the second line but this line should be indented to
    match the first line of the string.

您可以使用一个小功能wrapped来做到这一点:

import sys
import textwrap
import ruamel.yaml
from ruamel.yaml.scalarstring import PreservedScalarString

yaml_str = """\
ResourceIndicators:
  version: 1.0.0
  name: This is the name
  neType: Text
  category: Text
  description: The is the first line of the sentence and then we continue
    on to the second line but this line should be indented to match the
    first line of the string.
"""

def wrapped(s, width=60):
    return PreservedScalarString('\n'.join(textwrap.wrap(s, width=width)))

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
data['ResourceIndicators']['description'] = \
    wrapped(data['ResourceIndicators']['description'])
yaml.dump(data, sys.stdout)

但是请注意,加载后必须用空格替换值中的换行符。

如果不是这样,则需要创建一个带有特殊表示符的“ IndentedPlainString”类。