如何在 YAML 中将字符串拆分为多行?

Posted

技术标签:

【中文标题】如何在 YAML 中将字符串拆分为多行?【英文标题】:How do I break a string in YAML over multiple lines? 【发布时间】:2011-04-16 23:15:23 【问题描述】:

在 YAML 中,我有一个很长的字符串。我想将其保留在编辑器的 80 列(左右)视图中,因此我想断开字符串。这是什么语法?

换句话说,我有这个:

Key: 'this is my very very very very very very long string'

我想要这个(或类似的东西):

Key: 'this is my very very very ' +
     'long string'

我想使用上面的引号,所以我不需要转义字符串中的任何内容。

【问题讨论】:

快速提示:您不能在标量内放置注释,因此您不能注释多行键或值的一部分。必须将所需的行移出声明。 ***.com/questions/20890445/… 【参考方案1】:

5 6 NINE(或 63*,取决于如何你算)在 YAML 中编写多行字符串的不同方法。

TL;DR

大多数时候使用>:内部换行符被去掉了,尽管最后你得到了一个:

  key: >
    Your long
    string here.

如果您希望将这些换行符保留为 \n(例如,带有段落的嵌入式降价),请使用 |

  key: |
    ### Heading

    * Bullet
    * Points

如果您不想在末尾附加换行符,请改用 >-|-

如果您需要在单词中间分割行或想要将换行符按字面意思输入为\n,请使用"..."

  key: "Antidisestab\
   lishmentarianism.\n\nGet on it."

YAML 太疯狂了。

块标量样式(>|

这些允许\" 等字符不转义,并在字符串末尾添加新行(\n)。

> Folded style 删除字符串中的单个换行符(但在末尾添加一个,并将双换行符转换为单个换行符):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

保留额外的前导空格并导致额外的换行符。请参阅下面的注释。

建议:使用这个。通常这就是你想要的。

| Literal style 将字符串中的每个换行符转换为文字换行符,并在末尾添加一个:

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

这是来自YAML Spec 1.2的官方定义

标量内容可以用块表示法编写,使用文字样式(用“|”表示),其中所有换行符都很重要。或者,它们可以使用折叠样式(用“>”表示)编写,其中每个换行符都折叠到一个空格,除非它以空行或缩进更多的行结尾。

建议:使用它来插入 格式化文本(尤其是 Markdown)作为值。

带有块咀嚼指示器的块样式(>-|->+|+

您可以通过添加 block chomping indicator 字符来控制字符串中最后一个新行以及任何尾随空行 (\n\n) 的处理:

>, |: "clip": 保持换行,去掉尾随的空行。 >-, |-: "strip": 去掉换行,去掉尾随的空行。 >+, |+: "keep": 保持换行,保持尾随空行。

“流”标量样式( "'

这些具有有限的转义,并构造一个没有换行符的单行字符串。它们可以与键在同一行开始,也可以先使用额外的换行符,这些换行符被剥离。双倍换行符变成一个换行符。

plain style(不能转义,不能 #: 组合,第一个字符不能是"'或许多其他标点符号):

Key: this is my very very very 
  long string

建议:避免。可能看起来很方便,但您可能会因不小心使用禁止的标点符号并触发语法错误而自取其辱。

double-quoted style\" 必须用 \ 转义,换行符可以用文字 \n 序列插入,行可以连接不带空格,尾随 @ 987654377@):

Key: "this is my very very \"very\" loooo\
  ng string.\n\nLove, YAML."

"this is my very very \"very\" loooong string.\n\nLove, YAML."

建议:在非常具体的情况下使用。这是您可以在不添加空格的情况下跨行打破非常长的标记(如 URL)的唯一方法。也许在中间添加换行符很有用。

single-quoted style(文字'必须加倍,没有特殊字符,可能对表达以双引号开头的字符串有用):

Key: 'this is my very very "very"
  long string, isn''t it.'

"this is my very very \"very\" long string, isn't it."

建议:避免。好处很少,主要是不便。

带有缩进指示符的块样式

如果以上内容对您来说还不够,您可以添加一个“block indentation indicator”(在您的块咀嚼指示器之后,如果您有的话):

- >8
        My long string
        starts over here
- |+1
 This one
 starts here

注意:折叠样式中的前导空格 (>)

如果您在折叠样式的非第一行的开头插入额外的空格,它们将被保留,并带有一个额外的换行符。 (流样式不会发生这种情况。)Section 6.5:

此外,折叠不适用于包含前导空格的文本行周围的换行符。请注意,这样一个缩进较多的行可能只包含这样的前导空格。

- >
    my long
      string
                    
    many spaces above
- my long
      string
                    
    many spaces above
    

["my long\n string\n \nmany spaces above\n","my long string\nmany spaces above"]

总结

在此表中,_ 表示space character\n 表示“换行符”(javascript 中的 \n),“其他功能”下除外。 “前导空格”在第一行之后应用(建立缩进)

> | " ' >- >+ |- |+
Spaces/newlines converted as:
Trailing space → _ _ _ _ _ _
Leading space → \n_ \n_ \n_ \n_ \n_ \n_
Single newline → _ \n _ _ _ _ _ \n \n
Double newline → \n \n\n \n \n \n \n \n \n\n \n\n
Final newline → \n \n \n \n
Final double newline → \n\n \n\n
How to create a literal:
Single quote ' ' ' ' '' ' ' ' '
Double quote " " " \" " " " " "
Backslash \ \ \ \\ \ \ \ \ \
Other features
In-line newlines with \n ? ? ? ? ? ? ? ?
Spaceless newlines with \ ? ? ? ? ? ? ? ?
# or : in value ?
Can start on sameline as key ? ? ? ? ? ?

示例

注意“空格”前行的尾随空格。

- >
  very "long"
  'string' with

  paragraph gap, \n and        
  spaces.
- | 
  very "long"
  'string' with

  paragraph gap, \n and        
  spaces.
- very "long"
  'string' with

  paragraph gap, \n and        
  spaces.
- "very \"long\"
  'string' with

  paragraph gap, \n and        
  s\
  p\
  a\
  c\
  e\
  s."
- 'very "long"
  ''string'' with

  paragraph gap, \n and        
  spaces.'
- >- 
  very "long"
  'string' with

  paragraph gap, \n and        
  spaces.

[
  "very \"long\" 'string' with\nparagraph gap, \\n and         spaces.\n", 
  "very \"long\"\n'string' with\n\nparagraph gap, \\n and        \nspaces.\n", 
  "very \"long\" 'string' with\nparagraph gap, \\n and spaces.", 
  "very \"long\" 'string' with\nparagraph gap, \n and spaces.", 
  "very \"long\" 'string' with\nparagraph gap, \\n and spaces.", 
  "very \"long\" 'string' with\nparagraph gap, \\n and         spaces."
]

*2 块样式,每个都有 2 个可能的块压缩指示符(或没有),以及 9 个可能的缩进指示符(或没有),1 个普通样式和 2 个引用样式:2 x (2 + 1 ) x (9 + 1) + 1 + 2 = 63

其中一些信息也已汇总here。

【讨论】:

在 63 种语法中,您认为有一种可以让您在多行中拼写一个不应有换行符或空格的字符串吗?我的意思是在大多数编程语言中人们会写成"..." + "...",或者在 Bash 的换行符之前写反斜杠。 @pepoluan 我尝试了所有可能的组合,发现只有一个允许无空格连接:在字符串周围加上双引号,在换行符(和缩进)之前加上反斜杠。示例:data:text/plain;base64 ,dGVzdDogImZvb1wKICBiYXIiCg== @wvxvw 相反,我认为 YAML 对于许多常见用例(例如配置文件)来说是最糟糕的格式,尤其是因为大多数人都被它明显的简单性所吸引,只是为了实现很多后来发现它是一种极其复杂的格式。 YAML 使错误的东西看起来正确 - 例如,字符串数组中的一个字符串中的无害冒号 : 会使 YAML 将其解释为对象数组。它违反了principle of least astonishment。 又一个多行字符串语法 我总是难以记住“|”中的哪一个或 '>' 保留或删除换行符。在某个时候,我意识到,如果从左到右阅读,运算符会告诉您他们如何转换字符串。 '|'两边的高度相同,这意味着字符串也将保持相同的高度;而'>'在右边比左边小,这意味着它将把字符串从多行“压缩”到一行。只是想把那个助记符留在这里给那些还没有发现它的人。【参考方案2】:

使用 yaml 折叠样式。每行的缩进将被忽略。最后会插入一个换行符。

Key: >
  This is a very long sentence
  that spans several lines in the YAML
  but which will be rendered as a string
  with only a single carriage return appended to the end.

http://symfony.com/doc/current/components/yaml/yaml_format.html

您可以使用“block chomping indicator”来消除尾随换行符,如下:

Key: >-
  This is a very long sentence
  that spans several lines in the YAML
  but which will be rendered as a string
  with NO carriage returns.

在任何一种情况下,每个换行符都被一个空格替换。

还有其他可用的控制工具(例如用于控制缩进)。

见https://yaml-multiline.info/

【讨论】:

谢谢,但您不能将此语法用引号括起来,看来:引号在结果字符串中显示为文字。 不知何故在我的应用程序中翻译结束后立即添加了回车。这样,Javascript 将其视为多行并失败。 - 'key'|trans - 也不起作用。 根据我的经验,这种语法会在字符串末尾附加一个\n。这可能是也可能不是您想要的。 每个换行符被一个空格替换 @Rvanlaak 和 @rich-remer 使用 block chomper 避免末尾的换行符:>-【参考方案3】:

要保留换行符,请使用|,例如:

|
  This is a very long sentence
  that spans several lines in the YAML
  but which will be rendered as a string
  with newlines preserved.

被翻译为“这是一个很长的句子\n,它在 YAML 中跨越了几行‌\n,但将呈现为字符串‌\ n 保留换行符。\n"

【讨论】:

这对我来说似乎可以用两行但不是三行? 谢谢,就像你说的那样工作正常。出于某种原因,在 Pandoc 的 yaml 标头中,我需要在每一行重复 |,原因对我来说并不明显:groups.google.com/forum/#!topic/pandoc-discuss/xuqEmhWgf9A 如果我写这不是一个问题: - field1: |一二-field1: |三个代表' 我得到:一个\n两个\n 和三个\n?我会考虑 2 之后的 \n 不在那里... 当使用带分隔符的多行 cat 时,会导致在输出中添加前导空格(这是 YAML 所必需的)。 @Rubytastic 要在 Rails 生成的 HTML 页面中也包含这些断行,您需要采取一些预防措施。我已经在这里回答了:***.com/questions/10982706/…【参考方案4】:

1.块表示法(plain, flow-style, scalar): 删除块后换行符变为空格和额外的换行符

---
# Note: It has 1 new line after the string
content:
    Arbitrary free text
    over multiple lines stopping
    after indentation changes...

...

等效 JSON


 "content": "Arbitrary free text over multiple lines stopping after indentation changes..."

2。文字块标量:文字块标量 | 将包括换行符和任何尾随空格。但删除了额外的

块后的换行符。

---
# After string we have 2 spaces and 2 new lines
content1: |
 Arbitrary free text
 over "multiple lines" stopping
 after indentation changes...  


...

等效 JSON


 "content1": "Arbitrary free text\nover \"multiple lines\" stopping\nafter indentation changes...  \n"

3. + 带有字面块标量的指标: 在块后保留额外的换行符

---
# After string we have 2 new lines
plain: |+
 This unquoted scalar
 spans many lines.


...

等效 JSON


 "plain": "This unquoted scalar\nspans many lines.\n\n\n"

4. – 带有字面块标量的指标: 表示字符串末尾的换行符被删除。

---
# After string we have 2 new lines
plain: |-
 This unquoted scalar
 spans many lines.


...

等效 JSON


 "plain": "This unquoted scalar\nspans many lines."

5.折叠块标量(>):

会将换行符折叠成空格,但会在块之后删除多余的换行符。

---
folded_newlines: >
 this is really a
 single line of text
 despite appearances


...

等效 JSON


 "fold_newlines": "this is really a single line of text despite appearances\n"

更多信息可以访问我的Blog

【讨论】:

您是否打算例如#4 在冒号后使用“|-”?此外,您可能会在此处丢失“---”指令结束标记,因为您只显示一个文档。文档结束标记有助于突出显示文档中的尾随空格。不过,除此之外,不需要明确的文件。 感谢您的指出。那是一个错字。 A已经解决了这个问题。我提供了开始和结束标记,以便每个人都可以看到字符串后面的新行。 Nr.1 在 YAML 规范中被描述为一个普通的、流式的标量。将其称为块样式具有误导性。 将 Nr.1 更改为普通的流式标量。【参考方案5】:

要连接长行没有空格,请使用双引号并用反斜杠转义换行符:

key: "Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemp\
  orincididuntutlaboreetdoloremagnaaliqua."

(感谢@Tobia)

【讨论】:

谢谢,这真的帮助我定义了多行的 Docker 卷!如果有人有同样的问题,here is my solution on an Online YAML Parser 终于啊。我试图在 Puppet 的 Hiera yaml 文件中将长 ssh-keys 包装在多行中,但在我使用您的答案之前总是会出现不需要的空格。谢谢。【参考方案6】:

你可能不相信,但是 YAML 也可以做多行键:

?
 >
 multi
 line
 key
:
  value

【讨论】:

需要解释(什么是“?”)。 @ilyaigpetrov 完全按照所写的“多行”键。通常你会做key:value之类的事情,但是如果你的密钥包含换行符,你可以按照上面的描述来做 有任何实际使用案例的例子吗? @ilyaigpetrov ? 是关键指标(如映射中的键)。在许多情况下,当键后的(必需)值指示符: 使解析明确时,您可能会省略键指示符。但事实并非如此,您必须使用它来显式标记密钥。【参考方案7】:

如果您在 Symfony 中使用 YAML 和 Twig 进行翻译,并且想在 Javascript 中使用多行翻译,则在翻译后立即添加回车。所以即使是下面的代码:

var javascriptVariable = "- 'key'|trans -";

其中yml翻译如下:

key: >
    This is a
    multi line 
    translation.

仍然会在 html 中产生如下代码:

var javascriptVariable = "This is a multi line translation.
";

所以,Twig 中的减号并不能解决这个问题。解决方法是在 yml 中的大于号后面加上这个减号:

key: >-
    This is a
    multi line 
    translation.

会有正确的结果,在 Twig 中的一行上进行多行翻译:

var javascriptVariable = "This is a multi line translation.";

【讨论】:

这看起来像一个错误。你有机会提交错误报告吗?【参考方案8】:

对于字符串可能包含空格或不包含空格的情况,我更喜欢双引号和带有反斜杠的行继续:

key: "String \
  with long c\
  ontent"

但请注意,如果续行以空格开头,则需要对其进行转义(因为它将在其他地方被剥离):

key: "String\
  \ with lon\
  g content"

如果字符串包含换行符,则需要用 C 风格编写\n

另见this question。

【讨论】:

如果它在其他地方被剥离,即不在那个位置,您能否用关于它将被剥离的在哪里的信息更新您的答案。还请写下哪个解析器(针对哪种语言)可以做到这一点?我只看到解析器在就地删除多行引号字符串中的前导/尾随空格。【参考方案9】:

在 Jekyll 项目的 YAML 文件中,上述解决方案都不适合我。在尝试了许多选项后,我意识到使用<br> 进行 HTML 注入可能也可以,因为最终所有内容都呈现为 HTML:

名称:| 在拉曼查村<br> 我不想记住他的名字<br>

至少它对我有用。不知道与此方法相关的问题。

【讨论】:

您的解决方案涉及一个不同的问题:在您的情况下,您希望在处理 YAML 的结果中出现换行符。 HTML 和 YAML 之间没有隐含的关系。即使 YAML 会通过常规换行符,HTML 也会忽略它们。最终,操作的问题与在 YAML 本身中使用换行符有关,以防止很长的行。它不关心最终如何呈现数据。为什么要讲这个?因为这解释了为什么这里给出的所有其他解决方案都不适用于您的情况。

以上是关于如何在 YAML 中将字符串拆分为多行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C / Objective-C 中将字符串文字拆分为多行?

如何在 BigQuery SQL 中将字符串列拆分为多行单个单词和单词对?

在Oracle中将字符串拆分为多行

在Oracle中将字符串拆分为多行

在Oracle中将字符串拆分为多行

在Oracle中将字符串拆分为多行