如何在YAML中将字符串跨多行分隔并保留空格?

6
请注意,这个问题类似于这个问题,但仍然有所不同,因此那些答案无法解决我的问题:
  • 要插入控制字符(例如\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在线解析器中尝试此操作,结果如预期的那样呈现出"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


1
你能否提供一个标题和第一段,以更清楚地解释为什么这不是您链接到的现有问题的重复?特别是,您的情况有什么特殊之处,使得最受欢迎的答案中的任何技术都不适用?我认为可能您真正的问题是“如何保留多行字符串中的前导空格?”或类似的问题。 - IMSoP
完成。将对另一个问题的引用移至第一段,并在标题中加入“保留空格”。 - Joe
可能是重复的问题,参考如何将字符串分成多行? - codeforester
2个回答

3

不需要使用\x20,你可以直接转义行首的第一个非缩进空格:

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

这适用于多个空格,你只需要转义第一个。


1
您的观察是正确的,控制字符只能在双引号标量中表示。
然而,如果子行(在YAML中称为延续行)有前导空格,解析器不会“失败”。您对YAML标准的解释是不正确的。该标准明确规定,对于多行双引号标量
所有前导和尾随的空白字符都被排除在内容之外。
因此,您可以在long之前放置任意数量的空格,这不会有任何影响。
Python中双引号标量的表示者(无论是在ruamel.yaml还是PyYAML中)始终将换行符表示为\n。我不知道其他语言中的YAML表示者是否具有更多控制权(例如,使用双重换行符来表示\n),因此您可能需要编写自己的表示者。
在编写表示器时,您可以尝试使换行变得智能化,以最小化转义空格的数量(通过将它们放在同一行的单词之间)。但是,对于高双空格与单词比率相结合且可操作宽度较小的字符串,如果没有转义空格,则很难(甚至不可能)。 我认为这样的表达器应首先检查是否需要双引号(即除换行符外是否存在控制字符)。如果没有,并且有换行符,则最好表示字符串为块样式文字标量(其中行首或行尾的空格不被排除)。

1
我认为你过分解释了“失败”这个词。从问题中的下一句话可以清楚地看出,它只是意味着“未能给出期望的结果”,具体来说,在示例中未能保留“quite”和“long”之间的空格。问题中没有提到YAML规范,只是尝试了一些示例输入并未得到预期的结果,因此规范确认OP已经知道的前导空格信息是无关紧要的。 - IMSoP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接