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.

jjkparker
fonte

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/

Matt Williamson
fonte
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 .

Steve Bennett
fonte
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 "

Ali Shakiba
fonte
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

Arayan Singh
fonte
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
Mohsen
fonte
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)

phs
fonte
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.";
Rvanlaak
fonte
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 .

Joe
fonte
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.

Irene
fonte
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