Como quebro uma string em várias linhas?


1539

No YAML, eu tenho uma string que é muito longa. Eu quero manter isso dentro da visualização de 80 colunas (mais ou menos) do meu editor, então eu gostaria de quebrar a string. Qual é a sintaxe para isso?

Em outras palavras, eu tenho o seguinte:

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

e eu gostaria de ter isso (ou algo nesse sentido):

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

Eu gostaria de usar aspas como acima, para não precisar escapar de nada dentro da string.

Respostas:


979

Usando o estilo dobrado yaml, cada quebra de linha é substituída por um espaço. A indentação em cada linha será ignorada. Uma quebra de linha será inserida no final.

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

Você pode usar o "indicador de mastigação de bloco" para eliminar a quebra de linha à direita, da seguinte maneira:

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.

Existem outras ferramentas de controle disponíveis também (para controlar o recuo, por exemplo).

Veja https://yaml-multiline.info/


Obrigado, mas você não pode agrupar essa sintaxe entre aspas, ao que parece: as aspas aparecem como literais na sequência resultante.
Jjkparker 27/09/10

De alguma forma, um retorno de carro é adicionado logo após o final da tradução no meu aplicativo. Dessa forma, o Javascript o vê como várias linhas e falha. {{- 'key'|trans -}}também não funciona.
Rvanlaak

Como você obteria o mesmo efeito que um valor em uma lista?
Mikhail

cada quebra de linha é substituída por um espaço ou simplesmente removida?
Steve

2
cada quebra de linha é substituída por um espaço <- mas uma quebra de linha dupla será uma quebra de linha.
21819 Jean Jordaan

3354

Existem 5 6 NINE (ou 63 *, dependendo de como você conta) maneiras diferentes de escrever strings de várias linhas no YAML.

TL; DR

  • Geralmente você deseja >:

    key: >
      Your long
      string here.
    
  • Se você deseja que as quebras de linha sejam preservadas como \nna seqüência de caracteres (por exemplo, descontos incorporados com parágrafos), use |.

    key: |
      ### Heading
    
      * Bullet
      * Points
    
  • Use >-ou |-não, se você não quiser que uma quebra de linha seja anexada ao final.

  • Se você precisar dividir linhas no meio das palavras ou digitar literalmente quebras de linha como \n, use aspas duplas:

    key: "Antidisestab\
     lishmentarianism.\n\nGet on it."
    
  • YAML é louco.

Bloquear estilos escalares ( >, |)

Isso permite caracteres como \e "sem escapar e adiciona uma nova linha ( \n) ao final da sua string.

> O estilo dobrado remove as novas linhas da cadeia (mas adiciona uma no final e converte as novas linhas em simples):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

| O estilo literal transforma cada nova linha da string em uma nova linha literal e adiciona uma no final:

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

Aqui está a definição oficial do YAML Spec 1.2

O conteúdo escalar pode ser escrito em notação de bloco, usando um estilo literal (indicado por "|"), onde todas as quebras de linha são significativas. Como alternativa, eles podem ser escritos com o estilo dobrado (indicado por ">"), em que cada quebra de linha é dobrada em um espaço, a menos que termine uma linha vazia ou mais recuada.

Estilos de bloco com indicador mastigando bloco ( >-, |-, >+, |+)

Você pode controlar o manuseio da nova linha final na string e de qualquer linha em branco à direita ( \n\n) adicionando um caractere indicador de chomping de bloco :

  • >, |: "clip": mantenha o avanço da linha, remova as linhas em branco à direita.
  • >-, |-: "strip": remova a alimentação da linha, remova as linhas em branco à direita.
  • >+, |+: "keep": mantém o avanço da linha, continua seguindo linhas em branco.

"Flow" escalares estilos ( , ", ')

Eles têm escape limitado e constroem uma cadeia de caracteres de linha única sem novos caracteres de linha. Eles podem começar na mesma linha que a chave ou com novas linhas adicionais primeiro.

estilo simples (sem escape, sem#ou:combinações, limites para o primeiro caractere):

Key: this is my very very very 
  long string

estilo de aspas duplas (\e"deve ser escapado por\, novas linhas podem ser inseridas com uma\nsequêncialiteral, linhas podem ser concatenadas sem espaços com final\):

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

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

estilo de aspas simples (literal'deve ser duplicado, sem caracteres especiais, possivelmente útil para expressar cadeias começando com aspas duplas):

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

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

Sumário

Nesta tabela, _significa space character. \nsignifica "caractere de nova linha" ( \nem JavaScript), exceto a linha "novas linhas em linha", onde significa literalmente uma barra invertida e um 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       |

Exemplos

Observe os espaços à direita na linha antes de "espaços".

- >
  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."
]

Estilos de bloco com indicadores de indentação

Caso as opções acima não sejam suficientes, você pode adicionar um " indicador de indentação de bloco " (após o indicador de chomping de bloco, se você tiver um):

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

Termo aditivo

Se você inserir espaços extras no início das não-primeiras linhas no estilo Dobrado, eles serão mantidos, com uma nova linha de bônus. Isso não acontece com os estilos de fluxo:

- >
    my long
      string
- my long
    string

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

Eu não posso nem.

*2 estilos de bloco, cada um com 2 possíveis indicadores de chomping de bloco (ou nenhum) e com 9 possíveis indicadores de recuo (ou nenhum), 1 estilo simples e 2 estilos entre aspas: 2 x (2 + 1) x (9 + 1) + 1 + 2 = 63

Algumas dessas informações também foram resumidas aqui .


28
Entre as 63 sintaxes, você acha que existe uma única que permite soletrar em várias linhas uma sequência que não deve ter novas linhas nem espaços? Quero dizer o que alguém escreveria como "..." + "..."na maioria das linguagens de programação ou barra invertida antes da nova linha no Bash.
Tobia 28/07

23
@pepoluan Tentei todas as combinações possíveis e descobriu único que permite a concatenação sem espaço: colocar aspas em torno da corda e uma barra invertida antes de nova linha Exemplo: dados: text / plain; base64, dGVzdDogImZvb1wKICBiYXIiCg == (e recuo.)
Tobia

42
@wvxvw, pelo contrário, acho que o YAML é o pior formato para muitos casos de uso comuns (por exemplo, arquivos de configuração), principalmente porque a maioria das pessoas é atraída por sua aparente simplicidade apenas para perceber muito mais tarde que é um formato extremamente complexo. O YAML faz com que as coisas erradas pareçam corretas - por exemplo, um cólon inócuo :dentro de uma sequência em uma matriz de sequências faz com que o YAML a interprete como uma matriz de objetos. Isso viola o princípio de menos espanto .
Vicky Chijwani

20
Alguém criou um site sobre esse tópico: yaml-multiline.info @SteveBennett ㄹ Caso não tenha conhecimento, verifique o rodapé dessa página.
Udondan

38
Yet Another sintaxe da cadeia multi linha
xdhmoore

186

Para preservar novas linhas| , use , por exemplo:

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

é traduzido para "Esta é uma frase muito longa‌ \ n que abrange várias linhas no YAML‌ \ n, mas que será renderizada como uma string‌ \ n com novas linhas preservadas. \ n "


Isso parece funcionar bem para mim com duas linhas, mas não com três?
cboettig

Obrigado, funciona bem lá, como você diz. Por alguma razão nos cabeçalhos yaml de Pandoc, preciso repetir o |em cada linha, por razões que não são óbvias para mim: groups.google.com/forum/#!topic/pandoc-discuss/xuqEmhWgf9A
cboettig

1
Este exemplo NÃO se converte em novas linhas nos trilhos 4!
Rubytastic

Não é um problema o fato de que se eu escrever: - field1: | um dois - campo1: | três para 'eu recebo: um \ ndois \ ne três \ npara? Eu iria aspecto o \ n após 2 a não estar lá ...
Alain1405

Ao usar multilinha catcom delimitador, isso faz com que os espaços à esquerda (necessários para o YAML) sejam adicionados à saída.
Karl Richter

110

1. Notação de bloco (simples, estilo de fluxo, escalar): as novas linhas se tornam espaços e novas linhas extras após a remoção do bloco

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

...

JSON equivalente

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

2. Escalar em blocos literais: um escalar em blocos literais | incluirá as novas linhas e os espaços à direita. mas remove extra

novas linhas após o bloco.

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


...

JSON equivalente

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

3. + indicador com Escalar literal de bloco: mantenha novas linhas extras após o bloco

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


...

JSON equivalente

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

4. - indicador com Literal Block Scalar: - significa que a nova linha no final da string é removida.

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


...

JSON equivalente

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

5. Escalada de bloco dobrado (>):

dobrará novas linhas em espaços e removerá novas linhas adicionais após o bloco.

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


...

JSON equivalente

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

para mais você pode visitar meu blog


Você pretendeu, por exemplo, o nº 4 usar "| -" após os dois pontos? Além disso, você pode perder os marcadores finais das diretivas "---" aqui, pois está mostrando apenas um documento. Os marcadores de fim de documento são úteis para destacar o espaço em branco à direita nos documentos. Além disso, porém, não há necessidade de documentos explícitos.
22418 seh

obrigado por apontar. isso foi um erro de digitação. A consertou isso. Forneci marcador inicial e final para que todos possam ver novas linhas após a sequência.
Arayan Singh

Nr.1 é descrito como um escalar simples, de estilo de fluxo, na especificação YAML. Chamá-lo de estilo de bloco é enganoso.
Anthon

Altera o Nr.1 ​​como um escalar simples, no estilo de fluxo.
Arayan Singh

42

Você pode não acreditar, mas o YAML também pode executar chaves de várias linhas:

?
 >
 multi
 line
 key
:
  value

3
Explicação necessária (o que é "?").
Ilyaigpetrov 26/09

@ilyaigpetrov exatamente como está escrito, chave "multi-line". Normalmente você fazer coisas como key:value, mas se a sua chave contém nova-line, você pode fazê-lo como descrito acima
goFrendiAsgard

4
Algum exemplo de caso de uso do mundo real para isso?
Richard-Degenne

1
@ilyaigpetrov ?é o indicador principal (como na chave de um mapeamento). Em muitas situações, você pode deixar de fora o indicador de chave, quando o indicador de valor (obrigatório) :após a chave torna a análise inequívoca. Mas esse não é o caso, você precisará usar isso para marcar explicitamente a chave.
Anthon

42

Para concatenar linhas longas sem espaço em branco , use aspas duplas e escape das novas linhas com barras invertidas:

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

(Obrigado @Tobia)


Obrigado, isso realmente me ajudou a definir os volumes do Docker em várias linhas! Se alguém tem o mesmo problema, aqui está a minha solução em um YAML Analisador on-line
Mike Mitterer

Ah finalmente. Eu estava tentando envolver longas teclas ssh nos arquivos Hiera yaml do Puppet em várias linhas, mas sempre obtinha espaços indesejados até que eu usasse sua resposta. Obrigado.
Martijn Heemels

18

Caso você esteja usando YAML e Twig para traduções no Symfony e queira usar traduções de várias linhas em Javascript, um retorno de carro será adicionado logo após a tradução. Portanto, mesmo o seguinte código:

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

Qual possui a seguinte tradução yml:

key: >
    This is a
    multi line 
    translation.

Ainda resultará no seguinte código em html:

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

Portanto, o sinal de menos no Twig não resolve isso. A solução é adicionar este sinal de menos após o yml maior que:

key: >-
    This is a
    multi line 
    translation.

Terá o resultado adequado, tradução de várias linhas em uma linha no Twig:

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

Isso parece um bug. Você teve a chance de registrar um relatório de bug?
dreftymac

8

Para situações em que a string pode conter espaços ou não, prefiro aspas duplas e continuação de linha com barras invertidas:

key: "String \
  with long c\
  ontent"

Mas observe a armadilha do caso de uma linha de continuação começar com um espaço, ela precisa ser escapada (porque será removida em outro lugar):

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

Se a string contém quebras de linha, isso precisa ser escrito em estilo C \n.

Veja também esta pergunta .


Se for retirado em outro local , ou seja, não nessa posição, você pode atualizar sua resposta com informações sobre onde será retirado. Escreva também qual analisador (para qual idioma) faz isso? Eu só vi analisadores separarem esses espaços iniciais / finais em cadeias de aspas com várias linhas no lugar .
Anthon

0

Nenhuma das soluções acima funcionou para mim, em um arquivo YAML dentro de um projeto Jekyll. Depois de tentar muitas opções, percebi que uma injeção de HTML também <br>poderia funcionar, pois no final tudo é renderizado em HTML:

nome: | em uma vila de La Mancha, <br>cujo nome não <br>quero lembrar.

Pelo menos funciona para mim. Não faço ideia dos problemas associados a essa abordagem.


2
Sua solução refere-se a um problema diferente: no seu caso, você deseja que as quebras de linha apareçam no HTML renderizado como resultado do processamento do YAML. HTML e YAML não têm um relacionamento implícito entre si. E mesmo se o YAML passasse quebras de linha regulares, o HTML os ignoraria. Eventualmente, a pergunta do op está relacionada ao uso de quebras de linha no próprio YAML, apenas para evitar linhas muito longas. Ele não se importa com a forma como os dados podem ser renderizados no final. Por que contar isso? Porque isso explica por que todas as outras soluções fornecidas aqui não funcionam no seu caso.
Thomas Urban
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.