题 在YAML中,如何在多行中断字符串?


在YAML中,我有一个非常长的字符串。我想将它保留在我的编辑器的80列(或左右)视图中,所以我想打破字符串。这是什么语法?

换句话说,我有这个:

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

我想要这个(或者这个效果):

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

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


938
2017-09-24 19:47


起源




答案:


使用yaml折叠样式,每个换行符由空格替换。每行中的缩进将被忽略。

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

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


540
2017-09-24 19:54



谢谢,但你不能用引号括起这个语法,似乎:引号在结果字符串中显示为文字。 - jjkparker
我不认为你添加引号。该 >推断它是一个字符串。 - Matt Williamson
不知何故,在我的应用程序翻译结束后立即添加回车。这样Javascript将其视为多行并失败。 {{- 'key'|trans -}} 也不起作用。 - Rvanlaak
你如何获得与列表中的值相同的效果? - Mikhail
这个答案很好,但马特威廉姆森的答案应该是公认的答案。 - Travis Bear


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

块标量样式(>|

这些允许诸如的字符 \ 和 " 没有转义,并添加一个新行(\n)到你的字符串的末尾。

>  折叠式 删除字符串中的单个换行符(但最后添加一个换行符,并将双换行符转换为单个换行符):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

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

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

这是官方的定义 YAML Spec 1.2

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

使用块状咀嚼指示器阻止样式(>-|->+|+

您可以控制字符串中最后一个新行的处理以及任何尾随空白行(\n\n)通过添加一个 块咀嚼指标 字符:

  • >|:“剪辑”:保持换行,删除尾随空白行。
  • >-|-:“strip”:删除换行符,删除尾随空白行。
  • >+|+:“保持”:保持换行,保持尾随空行。

“流”标量样式("'

它们具有有限的转义,并构造一个没有换行符号的单行字符串。它们可以与键位于同一行,也可以首先使用其他换行符。

朴素的风格 (没有逃避,没有 # 要么 : 组合,第一个字符的限制):

Key: this is my very very very 
  long string

双引号风格 (\ 和 " 必须逃脱 \,可以用文字插入换行符 \n 序列,行可以连接,没有带尾随的空格 \):

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

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

单引号风格 (文字 ' 必须加倍,没有特殊字符,可能用于表示以双引号开头的字符串):

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

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

概要

在这张表中, _ 手段 space character\n 意思是“换行符”(\n 在JavaScript中),除了“in-line newlines”行,它的字面意思是反斜杠和n)。

                      >     |            "     '     >-     >+     |-     |+
-------------------------|------|-----|-----|-----|------|------|------|------  
Trailing spaces   | Kept | Kept |     |     |     | Kept | Kept | Kept | Kept
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 dbl nl's => |      |      |     |     |     |      | Kept |      | Kept  
In-line newlines  | No   | No   | No  | \n  | No  | No   | No   | No   | No
Spaceless newlines| No   | No   | No  | \   | No  | No   | No   | No   | No 
Single quote      | '    | '    | '   | '   | ''  | '    | '    | '    | '
Double quote      | "    | "    | "   | \"  | "   | "    | "    | "    | "
Backslash         | \    | \    | \   | \\  | \   | \    | \    | \    | \
" #", ": "        | Ok   | Ok   | No  | Ok  | Ok  | Ok   | Ok   | Ok   | Ok
Can start on same | No   | No   | Yes | Yes | Yes | No   | No   | No   | No
line 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."
]

使用缩进指示符阻止样式

如果以上情况对您不够,您可以添加“阻止压痕指示器“(在您的块咀嚼指示符之后,如果您有一个):

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

附录

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

- >
    my long
      string
- my long
    string

["my long\n string\n", "my long string"]

我甚至不能。

*2个块样式,每个样式有2个可能的块阻塞指示符(或者没有),并且有9个可能的缩进指示符(或者没有),1个简单样式和2个引用样式:2 x(2 + 1)x(9 + 1)+ 1 + 2 = 63

其中一些信息也已经汇总 这里


2250
2018-02-11 10:27



在63种语法中,你认为有一种语法允许你在多行中拼写一个不应该有换行符或空格的字符串吗?我的意思是一个人会写的 "..." + "..." 在大多数编程语言中,或在Bash中换行前的反斜杠。 - Tobia
@pepoluan我尝试了所有可能的组合,发现只有一个允许无空间连接:在字符串周围加上双引号,在换行符之前加上反斜杠(和缩进)。例如:data:text / plain; base64,dGVzdDogImZvb1wKICBiYXIiCg == - Tobia
啊,谢谢 - (尾随反斜杠=>没有空格)是我错过的一种行为。似乎是双引号字符串的唯一。 - Steve Bennett
@ wvxvw相反,我认为YAML是许多常见用例(例如配置文件)的最差格式,尤其是因为大多数人都被其明显的简单性所吸引,只是为了很晚才意识到这是一种非常复杂的格式。 YAML做错了事 看 对 - 例如,一个无害的结肠 : 在字符串数组中的一个字符串中,YAML将其解释为对象数组。它违反了 最不惊讶的原则。 - Vicky Chijwani
有人建立了一个关于这个主题的网站: yaml-multiline.info @SteveBennettㄹ如果您不知道,请检查该页面的页脚。 - udondan


保存 换行符 使用 |, 例如:

|
  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 保留换行符。“


149
2018-03-12 15:28



这对我来说似乎很好用两行而不是三行? - cboettig
@cboettig在这里试试: nodeca.github.io/js-yaml - Ali Shakiba
谢谢,就像你说的那样工作正常。出于某种原因,在Pandoc的yaml标题中,我需要重复一遍 | 在每一行,原因对我来说不明显: groups.google.com/forum/#!topic/pandoc-discuss/xuqEmhWgf9A - cboettig
此示例不会转换为rails 4中的新行! - Rubytastic
如果我写的话,这不是一个问题: - field1:|一两 - field1:|三个'我得到:一个\ n两个\ n和三个\ nfor?我会在2之后的方面表示不要在那里...... - Alain1405


您可能不相信,但YAML也可以执行多行键:

?
 >
 multi
 line
 key
:
  value

34
2017-10-24 21:17



需要说明(什么是“?”)。 - ilyaigpetrov
@ilyaigpetrov完全按照“多行”键写。通常你会这样做 key:value,但如果您的密钥包含换行符,则可以按上述方法执行 - goFrendiAsgard
这个真实用例的任何例子? - Richard-Degenne


1.块表示法:  删除块后,换行符将成为空格和额外的换行符

---
# 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. + Literal Block Scalar指标: 阻止之后保留额外的换行符

---
# 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. - 使用Literal Block Scalar的指标:  - 表示删除字符串末尾的换行符。

---
# 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"
}

更多你可以访问我的 博客


31
2018-04-06 05:08



您是否打算将示例#4在冒号后使用“| - ”?此外,您可以在此丢失“---”指令结束标记,因为您只显示一个文档。文档结束标记有助于突出显示文档中的尾随空格。但除此之外,不需要明确的文件。 - seh
谢谢你指出。这是一个错字。 A已经修好了。我提供了开始和结束标记,以便每个人都可以在字符串后面看到新行。 - Arayan Singh


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

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

(谢谢@Tobia)


22
2018-04-11 19:39



谢谢,这真的帮助我在多行上定义了Docker卷!如果有人有同样的问题, 这是我在线YAML Parser的解决方案 - Mike Mitterer
优秀,与Ansible完美搭配。 - gertas
啊终于啊。我试图在多行中将Puppet的Hiera yaml文件中的长ssh-keys包装起来但总是得到不需要的空格,直到我用你的答案。谢谢。 - Martijn Heemels


如果您在Symfony中使用yml和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.";

15
2018-05-06 15:02



这看起来像一个bug。您有机会提交错误报告吗? - dreftymac


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

key: "String \
  with long c\
  ontent"

但请注意延续线以空格开头的情况下的缺陷,需要进行转义(因为它会在其他地方被剥离):

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

如果字符串包含换行符,则需要以C样式编写 \n

也可以看看 这个问题


5
2017-09-06 08:13