如何在多行上打破一个字符串并在YAML中保留空格?

时间:2017-09-05 17:31:41

标签: string yaml

请注意,问题与this one类似,但仍然不同,以便这些答案无法解决我的问题:

  • 用于插入控制字符,例如\x08,似乎我必须使用双引号"
  • 所有空间都需要完全按照给定的方式保存。对于换行符,我明确使用了\n

我有一些我需要存储在YAML中的字符串数据,例如:

  • " This is my quite long string data "
  • "This is my quite long string data"
  • "This_is_my_quite_long_string_data"
  • "Sting data\nwhich\x08contains control characters"

并在YAML中需要它,如下所示:

Key: "  This  is  my" +
     "  quite  long " +
     " string  data  "

只要我停留在一条线上就没有问题,但我不知道如何将字符串内容放到多行。

YAML块标量样式(>|)在这里没有帮助,因为它们不允许转义,它们甚至会进行一些空格剥离,换行/空格替换对我来说没用。

看起来唯一的方法似乎是使用双引号"和反斜杠\,如下所示:

Key: "\
  This is \
  my quite \
  long string data\
  "

YAML online parser中尝试此操作会产生"This is my quite long string data"预期效果。

但不幸的是,如果其中一个"子线"有这样的领先空间:

Key: "\
  This is \
  my quite\
   long st\
  ring data\
  "

这会导致"This is my quitelong string data",删除此示例中的quitelong字词之间的空格。我想要解决的唯一问题就是用\x20替换每个子行的第一个前导空格,如下所示:

Key: "\
  This is \
  my quite\
  \x20long st\
  ring data\
  "

由于我选择了YAML以获得最佳的人类可读格式,我发现\x20有点丑陋的解决方案。也许有人知道更好的方法吗?

为了保持人类的可读性,我也不想使用!!binary

2 个答案:

答案 0 :(得分:2)

而不是\x20,您可以简单地转义该行上的第一个非缩进空间:

Key: "\
  This is \
  my quite\
  \ long st\
  ring data\
  "

这适用于多个空格,您只需要逃避第一个空格。

答案 1 :(得分:1)

您的观察结果是正确的,控制字符只能用双引号标量表示。

然而,如果子行(在YAML中说:延续行)具有前导空格,则解析器不会失败。您对YAML标准的解释是不正确的。标准明确指出对于多行double quoted scalars

  

内容中不包括所有前导和尾随空格字符。

因此,您可以根据需要在long之前放置任意数量的空格,这不会产生任何影响。

Python的双引号标量的代表(在ruamel.yaml和PyYAML中)总是将换行符表示为\n。我不知道其他语言中的YAML代表,你可以更好地控制它(例如,在双引号标量中用双倍换行代表\n)。所以你可能要编写自己的代表。

在编写代表时,您可以尝试使断行变得聪明,因为它最大限度地减少了转义空间的数量(通过将它们放在同一行上的单词之间)。 但是特别是对于具有高双倍空间与字比的字符串,加上一个小宽度来操作,如果没有转义空格将很难(如果不是不可能)。

这样的代表应该首先检查IMO是否需要双引号(即除了换行符之外还有控制字符)。如果没有,并且有换行符,则可能更好地将字符串表示为块样式文字标量(不排除行开头或结尾处的空格)。