Come faccio a spezzare una stringa su più righe?


1539

In YAML, ho una stringa molto lunga. Voglio mantenerlo all'interno della vista di circa 80 colonne del mio editor, quindi vorrei spezzare la stringa. Qual è la sintassi per questo?

In altre parole, ho questo:

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

e mi piacerebbe avere questo (o qualcosa in tal senso):

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

Vorrei usare le virgolette come sopra, quindi non ho bisogno di sfuggire a nulla all'interno della stringa.

Risposte:


979

Utilizzando lo stile piegato in yaml, ogni interruzione di riga viene sostituita da uno spazio. L'indentazione in ciascuna riga verrà ignorata. Un'interruzione di riga verrà inserita alla fine.

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

È possibile utilizzare l '"indicatore di blocco chomping" per eliminare l'interruzione della riga finale, come segue:

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.

Sono disponibili anche altri strumenti di controllo (ad esempio per controllare il rientro).

Vedi https://yaml-multiline.info/


Grazie, ma non puoi racchiudere questa sintassi tra virgolette, a quanto pare: le virgolette appaiono come letterali nella stringa risultante.
jjkparker,

In qualche modo un ritorno a capo viene aggiunto subito dopo la fine della traduzione nella mia app. In questo modo Javascript lo vede come più righe e fallisce. {{- 'key'|trans -}}non funziona neanche.
Rvanlaak,

Come otterresti questo stesso effetto come valore in un elenco?
Mikhail,

ogni interruzione di riga viene sostituita da uno spazio o semplicemente rimossa?
Steve,

2
ogni interruzione di riga è sostituita da uno spazio <- ma un'interruzione di doppia linea sarà un'interruzione di riga.
Jean Jordaan,

3354

Esistono 5 6 NOVE (o 63 *, a seconda del conteggio) diversi modi per scrivere stringhe su più righe in YAML.

TL; DR

  • Di solito, vuoi >:

    key: >
      Your long
      string here.
    
  • Se si desidera conservare le interruzioni di riga come \nnella stringa (ad esempio, markdown incorporato con paragrafi), utilizzare |.

    key: |
      ### Heading
    
      * Bullet
      * Points
    
  • Utilizzare >-o |-invece se non si desidera aggiungere un'interruzione di riga alla fine.

  • Se devi dividere le linee nel mezzo di parole o digitare letteralmente le interruzioni di riga come \n, usa invece le virgolette doppie:

    key: "Antidisestab\
     lishmentarianism.\n\nGet on it."
    
  • YAML è pazzo.

Blocca stili scalari ( >,| )

Questi consentono caratteri come \e "senza escape e aggiungono una nuova riga ( \n) alla fine della stringa.

> Lo stile piegato rimuove le singole nuove righe all'interno della stringa (ma ne aggiunge una alla fine e converte le doppie nuove righe in singoli):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

| Lo stile letterale trasforma ogni nuova riga all'interno della stringa in una nuova riga letterale e ne aggiunge una alla fine:

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

Ecco la definizione ufficiale dalla YAML Spec 1.2

Il contenuto scalare può essere scritto in notazione a blocchi, usando uno stile letterale (indicato da “|”) in cui tutte le interruzioni di riga sono significative. In alternativa, possono essere scritti con lo stile piegato (indicato da “>”) in cui ogni interruzione di riga viene piegata in uno spazio a meno che non termini una riga vuota o più rientrata.

Stili di blocco con blocco chomping indicatore ( >-, |-, >+,|+ )

È possibile controllare la gestione della nuova riga finale nella stringa e di eventuali righe vuote finali ( \n\n) aggiungendo un carattere indicatore di blocco chomping :

  • >, |: "clip": mantiene l'avanzamento riga, rimuove le righe vuote finali.
  • >-, |-: "strip": rimuove l'alimentazione di riga, rimuove le righe vuote finali.
  • >+, |+: "keep": mantieni l'alimentazione della riga, continua a trascinare le righe vuote.

"Flow" stili scalari ( , ", ')

Questi hanno un escape limitato e costruiscono una stringa a riga singola senza caratteri di nuova riga. Possono iniziare sulla stessa riga del tasto o prima con nuove righe aggiuntive.

stile semplice (senza escape, no#o:combinazioni, limiti per il primo carattere):

Key: this is my very very very 
  long string

stile tra virgolette (\e"deve essere evitato da\, le nuove righe possono essere inserite con una\nsequenzaletterale, le righe possono essere concatenate senza spazi con trascinamento\):

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

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

stile a virgoletta singola (il valore letterale'deve essere raddoppiato, nessun carattere speciale, possibilmente utile per esprimere stringhe che iniziano con virgolette doppie):

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

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

Sommario

In questa tabella, _significa space character. \nsignifica "carattere newline" ( \nin JavaScript), ad eccezione della riga "newline in-line", dove significa letteralmente una barra rovesciata e una 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       |

Esempi

Nota gli spazi finali sulla riga prima di "spazi".

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

Blocca gli stili con gli indicatori di rientro

Nel caso in cui quanto sopra non fosse abbastanza per te, puoi aggiungere un " indicatore di indentazione del blocco " (dopo l'indicatore di chomping del blocco, se ne hai uno):

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

appendice

Se inserisci spazi extra all'inizio delle prime righe in stile Piegato, verranno mantenuti con una nuova riga bonus. Questo non accade con gli stili di flusso:

- >
    my long
      string
- my long
    string

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

Non posso nemmeno.

*2 stili di blocco, ciascuno con 2 possibili indicatori di blocco dei blocchi (o nessuno) e con 9 possibili indicatori di rientro (o nessuno), 1 stile normale e 2 stili tra virgolette: 2 x (2 + 1) x (9 + 1) + 1 + 2 = 63

Alcune di queste informazioni sono state anche riassunte qui .


28
Tra le 63 sintassi, pensi che ce ne sia una sola che ti permetta di scrivere in più righe una stringa che non dovrebbe avere newline o spazi? Intendo quello che si potrebbe scrivere come "..." + "..."nella maggior parte dei linguaggi di programmazione, o una barra rovesciata prima di Newline in Bash.
Tobia,

23
@pepoluan Ho provato ogni possibile combinazione e ne ho trovata solo una che consente una concatenazione senza spazio: metti virgolette doppie attorno alla stringa e una barra rovesciata prima di newline (e rientro) Esempio: dati: text / plain; base64, dGVzdDogImZvb1wKICBiYXIiCg ==
Tobia

42
@wvxvw al contrario, penso che YAML sia il formato peggiore per molti casi d'uso comuni (ad es. file di configurazione), anche perché la maggior parte delle persone è attratta dalla sua apparente semplicità solo per rendersi conto molto più tardi che è un formato estremamente complesso. YAML fa apparire le cose sbagliate , ad esempio due punti innocui :all'interno di una stringa in una matrice di stringhe fanno sì che YAML la interpreti come una matrice di oggetti. Viola il principio del minimo stupore .
Vicky Chijwani,

20
Qualcuno ha creato un sito Web su questo argomento: yaml-multiline.info @SteveBennett ㄹ Nel caso in cui non fossi a conoscenza, controlla il piè di pagina di quella pagina.
udondan

38
Ancora un'altra sintassi della stringa Multi Line
xdhmoore,

186

Per preservare l' uso di newline| , ad esempio:

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

è tradotto in "Questa è una frase molto lunga‌ \ n che si estende su più righe nello YAML‌ \ n ma che sarà resa come una stringa‌ \ n con le nuove righe conservate. \ n "


Questo sembra funzionare bene per me con due righe ma non con tre?
cboettig,

Grazie, funziona bene proprio come dici tu. Per qualche motivo nelle intestazioni di yaml di Pandoc, devo ripetere il comando |su ogni riga, per motivi che non sono ovvi per me: groups.google.com/forum/#!topic/pandoc-discuss/xuqEmhWgf9A
cboettig

1
Questo esempio NON viene convertito in nuove linee nelle rotaie 4!
Rubytastic,

Non è un problema il fatto che se scrivo: - field1: | uno due - campo1: | tre per 'I get: one \ ntwo \ n e three \ nfor?
Aspetterei

Quando si utilizza multilinea catcon delimitatore, ciò provoca l'aggiunta di spazi iniziali (necessari per YAML) all'output.
Karl Richter,

110

1. Notazione a blocchi (semplice, stile flusso, scalare): le nuove linee diventano spazi e le nuove linee extra dopo la rimozione del blocco

---
# 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. Scalare letteralmente a blocchi: uno scalare letterale a blocchi |includerà le newline e tutti gli spazi finali. ma rimuove extra

newline dopo il blocco.

---
# 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. Indicatore + con blocco letterale scalare: mantenere ulteriori righe dopo il blocco

---
# 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. - Indicatore con blocco letterale scalare: - significa che la nuova riga alla fine della stringa viene rimossa.

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


...

JSON equivalente

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

5. Scalare blocco piegato (>):

piegherà le nuove linee negli spazi e rimuoverà le nuove linee dopo il blocco.

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

per di più puoi visitare il mio blog


Intendevi ad esempio # 4 di usare "| -" dopo i due punti? Inoltre, puoi perdere i marcatori finali delle direttive "---" qui, poiché stai mostrando un solo documento. Gli indicatori di fine documento sono utili per evidenziare lo spazio bianco finale nei documenti. A parte questo, tuttavia, non sono necessari documenti espliciti.
seh

grazie per la segnalazione. quello era un errore di battitura. A l'hanno risolto. Ho fornito l'indicatore di inizio e fine in modo che tutti possano vedere nuove righe dopo la stringa.
Arayan Singh,

Il n. 1 è descritto come un semplice scalare di tipo flusso nella specifica YAML. Chiamarlo in stile blocco è fuorviante.
Anthon,

Cambia n. 1 come semplice, scalare in stile flusso.
Arayan Singh,

42

Potresti non crederci, ma YAML può fare anche chiavi multilinea:

?
 >
 multi
 line
 key
:
  value

3
Spiegazione necessaria (che cos'è "?").
ilyaigpetrov,

@ilyaigpetrov esattamente come scritto, chiave "multi-linea". Di solito fai cose del genere key:value, ma se la tua chiave contiene una nuova riga, puoi farlo come descritto sopra
goFrendiAsgard

4
Qualche esempio di un caso d'uso reale per questo?
Richard-Degenne,

1
@ilyaigpetrov ?è l'indicatore chiave (come nella chiave in una mappatura). In molte situazioni è possibile tralasciare l'indicatore chiave, quando l'indicatore del valore (richiesto) :dopo il tasto rende l'analisi non ambigua. Ma non è così, dovrai usarlo per contrassegnare esplicitamente la chiave.
Anthon,

42

Per concatenare le righe lunghe senza spazi bianchi , utilizzare le virgolette doppie e sfuggire alle nuove righe con barre rovesciate:

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

(Grazie @Tobia)


Grazie, questo mi ha davvero aiutato a definire i volumi Docker su più righe! Se qualcuno ha lo stesso problema, ecco la mia soluzione su un Parser YAML online
Mike Mitterer,

Ah finalmente. Stavo cercando di avvolgere lunghe chiavi ssh nei file yaml di Puppet Hiera su più righe ma ho sempre avuto spazi indesiderati fino a quando non ho usato la tua risposta. Grazie.
Martijn Heemels,

18

Nel caso in cui tu stia utilizzando YAML e Twig per le traduzioni in Symfony e desideri utilizzare le traduzioni multilinea in Javascript, un ritorno a capo viene aggiunto subito dopo la traduzione. Quindi anche il seguente codice:

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

Che ha la seguente traduzione yml:

key: >
    This is a
    multi line 
    translation.

Si tradurrà comunque nel seguente codice in HTML:

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

Quindi, il segno meno in Twig non risolve questo problema. La soluzione è aggiungere questo segno meno dopo il maggiore di accedi yml:

key: >-
    This is a
    multi line 
    translation.

Avrà il risultato corretto, traduzione su più righe su una riga in Twig:

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

Sembra un bug. Hai avuto la possibilità di presentare una segnalazione di bug?
Dreftymac,

8

Per le situazioni in cui la stringa potrebbe contenere spazi o meno, preferisco virgolette doppie e continuazione di riga con barre rovesciate:

key: "String \
  with long c\
  ontent"

Ma nota la trappola per il caso in cui una linea di continuazione inizia con uno spazio, deve essere sfuggita (perché verrà strappata altrove):

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

Se la stringa contiene interruzioni di riga, questa deve essere scritta in stile C. \n .

Vedi anche questa domanda .


Se viene rimosso altrove , ovvero non in quella posizione, è possibile aggiornare la risposta con informazioni su dove verrà rimosso. Per favore scrivi anche quale parser (per quale lingua) lo fa? Ho visto solo i parser striscia come leader / spazi finali tra virgolette multilinea stringhe in atto .
Anthon,

0

Nessuna delle soluzioni di cui sopra ha funzionato per me, in un file YAML all'interno di un progetto Jekyll. Dopo aver provato molte opzioni, mi sono reso conto che <br>potrebbe anche fare un'iniezione HTML con , poiché alla fine tutto è reso in HTML:

nome: | in un villaggio di La Mancha di <br>cui non <br>voglio ricordare il nome.

Almeno funziona per me. Nessuna idea sui problemi associati a questo approccio.


2
La tua soluzione si riferisce a un problema diverso: nel tuo caso vuoi che le interruzioni di riga vengano visualizzate in HTML renderizzato come risultato dell'elaborazione di YAML. HTML e YAML non hanno una relazione implicita tra loro. E anche se YAML superasse le normali interruzioni di riga, HTML le ignorerebbe. Alla fine la domanda dell'op è correlata all'uso delle interruzioni di riga nello stesso YAML solo per evitare linee molto lunghe. Non importa come i dati potrebbero essere resi alla fine. Perché dirlo? Perché questo spiega perché tutte le altre soluzioni fornite qui non funzionano nel tuo caso.
Thomas Urban,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.