Comment rompre une chaîne sur plusieurs lignes?

1539

En YAML, j'ai une chaîne très longue. Je veux garder cela dans la vue de 80 colonnes (ou plus) de mon éditeur, donc je voudrais casser la chaîne. Quelle est la syntaxe pour cela?

En d'autres termes, j'ai ceci:

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

et j'aimerais avoir ceci (ou quelque chose à cet effet):

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

Je voudrais utiliser des guillemets comme ci-dessus, donc je n'ai pas besoin d'échapper quoi que ce soit dans la chaîne.

jjkparker
la source

Réponses:

979

En utilisant le style plié en yaml, chaque saut de ligne est remplacé par un espace. L'indentation dans chaque ligne sera ignorée. Un saut de ligne sera inséré à la fin.

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

Vous pouvez utiliser l'indicateur de blocage de bloc pour éliminer la coupure de ligne de fin, comme suit:

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.

Il existe également d'autres outils de contrôle (pour contrôler l'indentation par exemple).

Voir https://yaml-multiline.info/

Matt Williamson
la source
Merci, mais vous ne pouvez pas encapsuler cette syntaxe entre guillemets, il semble: les guillemets apparaissent sous forme de littéraux dans la chaîne résultante.
jjkparker
D'une manière ou d'une autre, un retour chariot est ajouté juste après la fin de la traduction dans mon application. De cette façon, Javascript le voit comme plusieurs lignes et échoue. {{- 'key'|trans -}}ne fonctionne pas non plus.
Rvanlaak
Comment obtiendriez-vous ce même effet qu'une valeur dans une liste?
Mikhail
chaque saut de ligne est remplacé par un espace ou simplement supprimé?
Steve
2
chaque saut de ligne est remplacé par un espace <- mais un saut de ligne double sera un saut de ligne.
Jean Jordaan
3356

Il y a 5 6 NEUF (ou 63 *, selon la façon dont vous comptez) différentes façons d'écrire des chaînes multilignes en YAML.

TL; DR

  • En général, vous voulez >:

    key: >
      Your long
      string here.
    
  • Si vous souhaitez que les sauts de ligne soient conservés comme \ndans la chaîne (par exemple, démarque intégrée avec des paragraphes), utilisez |.

    key: |
      ### Heading
    
      * Bullet
      * Points
    
  • Utilisez >-ou à la |-place si vous ne souhaitez pas ajouter de saut de ligne à la fin.

  • Si vous devez fractionner des lignes au milieu des mots ou taper littéralement des sauts de ligne comme \n, utilisez plutôt des guillemets:

    key: "Antidisestab\
     lishmentarianism.\n\nGet on it."
    
  • YAML est fou.

Bloquer les styles scalaires ( >, |)

Ceux-ci autorisent les caractères tels que \et "sans s'échapper, et ajoutent une nouvelle ligne ( \n) à la fin de votre chaîne.

> Le style plié supprime les sauts de ligne simples dans la chaîne (mais en ajoute un à la fin et convertit les doubles sauts de ligne en simples):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

| Le style littéral transforme chaque nouvelle ligne de la chaîne en une nouvelle ligne littérale et en ajoute une à la fin:

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

Voici la définition officielle de la spécification YAML 1.2

Le contenu scalaire peut être écrit en notation bloc, en utilisant un style littéral (indiqué par «|») où tous les sauts de ligne sont significatifs. Alternativement, ils peuvent être écrits avec le style plié (désigné par «>») où chaque saut de ligne est plié en un espace à moins qu'il ne termine une ligne vide ou plus en retrait.

Styles de bloc avec bloc indicateur chomping ( >-, |-, >+, |+)

Vous pouvez contrôler le traitement de la nouvelle ligne finale de la chaîne et de toutes les lignes vides de fin ( \n\n) en ajoutant un caractère indicateur de hachage de bloc :

  • >, |: "clip": conservez le saut de ligne, supprimez les lignes vierges de fin.
  • >-, |-: "strip": supprimez le saut de ligne, supprimez les lignes vierges de fin.
  • >+, |+: "garder": garder le saut de ligne, garder les lignes vides à la fin.

Styles scalaires "Flow" ( , ", ')

Ceux-ci ont un échappement limité et construisent une chaîne d'une seule ligne sans nouveaux caractères de ligne. Ils peuvent commencer sur la même ligne que la clé, ou avec des retours à la ligne supplémentaires en premier.

style simple (pas d'échappement, non#ou:combinaisons, limites sur le premier caractère):

Key: this is my very very very 
  long string

style entre guillemets (\et"doit être échappé par\, les sauts de ligne peuvent être insérés avec une\nséquencelittérale, les lignes peuvent être concaténées sans espaces avec des espaces\):

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

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

style guillemet simple (le littéral'doit être doublé, pas de caractères spéciaux, peut-être utile pour exprimer des chaînes commençant par des guillemets doubles):

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

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

Sommaire

Dans ce tableau, _signifie space character. \nsignifie "caractère de nouvelle ligne" ( \nen JavaScript), à l'exception de la ligne "nouvelles lignes en ligne", où il signifie littéralement une barre oblique inverse et un 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       |

Exemples

Notez les espaces de fin sur la ligne avant «espaces».

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

Styles de bloc avec indicateurs d'indentation

Juste au cas où ce qui précède ne vous suffit pas, vous pouvez ajouter un " indicateur d'indentation de bloc " (après votre indicateur de blocage de bloc, si vous en avez un):

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

Addenda

Si vous insérez des espaces supplémentaires au début des lignes qui ne sont pas les premières dans le style Plié, elles seront conservées, avec une nouvelle ligne bonus. Cela ne se produit pas avec les styles de flux:

- >
    my long
      string
- my long
    string

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

Je ne peux même pas.

*2 styles de bloc, chacun avec 2 indicateurs de compression de bloc possibles (ou aucun), et avec 9 indicateurs d'indentation possibles (ou aucun), 1 style simple et 2 styles cités: 2 x (2 + 1) x (9 + 1) + 1 + 2 = 63

Certaines de ces informations ont également été résumées ici .

Steve Bennett
la source
28
Parmi les 63 syntaxes, pensez-vous qu'il en existe une seule qui vous permet d'épeler sur plusieurs lignes une chaîne qui ne devrait pas avoir de nouvelle ligne ni d'espace? Je veux dire ce que l'on écrirait comme "..." + "..."dans la plupart des langages de programmation, ou une barre oblique inverse avant la nouvelle ligne dans Bash.
Tobia
23
@pepoluan J'ai essayé toutes les combinaisons possibles et n'en ai trouvé qu'une qui permet une concaténation sans espace: mettez des guillemets doubles autour de la chaîne et une barre oblique inverse avant la nouvelle ligne (et l'indentation.) Exemple: data: text / plain; base64, dGVzdDogImZvb1wKICBiYXIiCg ==
Tobia
42
@wvxvw au contraire, je pense que YAML est le pire format pour de nombreux cas d'utilisation courants (par exemple, les fichiers de configuration), notamment parce que la plupart des gens sont attirés par son apparente simplicité pour se rendre compte beaucoup plus tard qu'il s'agit d'un format extrêmement complexe. YAML fait que les choses erronées semblent correctes - par exemple, un deux-points inoffensif :dans une chaîne dans un tableau de chaînes fait que YAML l'interprète comme un tableau d'objets. Il viole le principe du moindre étonnement .
Vicky Chijwani
20
Quelqu'un a créé un site Web sur ce sujet: yaml-multiline.info @SteveBennett ㄹ Au cas où vous ne seriez pas au courant, consultez le pied de page de cette page.
udondan
38
Encore une autre syntaxe de chaîne multi-lignes
xdhmoore
186

Pour conserver les sauts de ligne, utilisez |par exemple:

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

est traduit par "Ceci est une très longue phrase‌ \ n qui s'étend sur plusieurs lignes dans le YAML‌ \ n mais qui sera rendue sous forme de chaîne‌ \ n avec des retours à la ligne préservés. \ n "

Ali Shakiba
la source
Cela semble bien fonctionner pour moi avec deux lignes mais pas avec trois?
cboettig
Merci, ça marche bien comme vous le dites. Pour une raison quelconque dans les en-têtes yaml de Pandoc, je dois répéter la |sur chaque ligne, pour des raisons qui ne me paraissent
cboettig
1
Cet exemple ne convertit PAS en nouvelles lignes dans les rails 4!
Rubytastic
N'est-ce pas un problème le fait que si j'écris: - field1: | un deux - champ1: | trois pour «je reçois: un \ ndeux \ n et trois \ npour? J'aurais un aspect le \ n après 2 pour ne plus être là ...
Alain1405
Lorsque vous utilisez multiligne catavec délimiteur, cela entraîne l'ajout d'espaces de début (qui sont nécessaires pour YAML) à la sortie.
Karl Richter
110

1. Notation de bloc (simple, de style fluide, scalaire): les nouvelles lignes deviennent des espaces et des nouvelles lignes supplémentaires après la suppression du bloc

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

...

JSON équivalent

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

2. Scalaire bloc littéral: Un scalaire bloc littéral | comprendra les sauts de ligne et les espaces de fin. mais supprime extra

nouvelles lignes après le bloc.

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


...

JSON équivalent

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

3. + indicateur avec Literal Block Scalar: gardez les nouvelles lignes supplémentaires après le bloc

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


...

JSON équivalent

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

4. - indicateur avec Literal Block Scalar: - signifie que la nouvelle ligne à la fin de la chaîne est supprimée.

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


...

JSON équivalent

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

5. Bloc scalaire plié (>):

pliera les sauts de ligne en espaces et supprimera les sauts de ligne supplémentaires après le bloc.

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


...

JSON équivalent

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

pour plus vous pouvez visiter mon Blog

Arayan Singh
la source
Avez-vous l'intention par exemple # 4 d'utiliser "| -" après les deux points? De plus, vous pouvez perdre les marqueurs de fin des directives "---" ici, car vous n'affichez qu'un seul document. Les marqueurs de fin de document sont utiles pour mettre en évidence les espaces de fin dans les documents. En dehors de cela, cependant, il n'y a pas besoin de documents explicites.
seh
merci d'avoir souligné. c'était une faute de frappe. J'ai corrigé ça. J'ai fourni un marqueur de début et de fin pour que tout le monde puisse voir de nouvelles lignes après la chaîne.
Arayan Singh
Nr.1 est décrit comme un scalaire simple de type flux dans la spécification YAML. L'appeler style bloc est trompeur.
Anthon
Change Nr.1 ​​comme un scalaire simple, de style fluide.
Arayan Singh
42

Vous ne le croyez peut-être pas, mais YAML peut également utiliser des touches multi-lignes:

?
 >
 multi
 line
 key
:
  value
Mohsen
la source
3
Explication nécessaire (qu'est-ce que "?").
ilyaigpetrov
@ilyaigpetrov exactement comme écrit, touche "multiligne". Habituellement, vous faites des choses comme key:value, mais si votre clé contient une nouvelle ligne, vous pouvez le faire comme décrit ci-dessus
goFrendiAsgard
4
Un exemple de cas d'utilisation réel pour cela?
Richard-Degenne
1
@ilyaigpetrov ?est l'indicateur clé (comme dans la clé dans une cartographie). Dans de nombreuses situations, vous pouvez omettre l'indicateur clé, lorsque l'indicateur de valeur (requis) :après la clé rend l'analyse non ambiguë. Mais ce n'est pas le cas, vous devrez l'utiliser pour marquer explicitement la clé.
Anthon
42

Pour concaténer de longues lignes sans espace , utilisez des guillemets doubles et échappez aux nouvelles lignes avec des barres obliques inverses:

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

(Merci @Tobia)

phs
la source
Merci, cela m'a vraiment aidé à définir les volumes Docker sur plusieurs lignes! Si quelqu'un a le même problème, voici ma solution sur un analyseur YAML en ligne
Mike Mitterer
Ah enfin. J'essayais d'encapsuler de longues clés ssh dans les fichiers yaml Hiera de Puppet sur plusieurs lignes, mais j'ai toujours obtenu des espaces indésirables jusqu'à ce que j'utilise votre réponse. Merci.
Martijn
18

Si vous utilisez YAML et Twig pour des traductions dans Symfony et que vous souhaitez utiliser des traductions multilignes en Javascript, un retour chariot est ajouté juste après la traduction. Donc, même le code suivant:

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

Qui a la traduction yml suivante:

key: >
    This is a
    multi line 
    translation.

Donnera toujours le code suivant en html:

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

Ainsi, le signe moins dans Twig ne résout pas ce problème. La solution consiste à ajouter ce signe moins après le signe supérieur à en yml:

key: >-
    This is a
    multi line 
    translation.

Aura le bon résultat, la traduction multi-ligne sur une seule ligne dans Twig:

var javascriptVariable = "This is a multi line translation.";
Rvanlaak
la source
Cela ressemble à un bug. Avez-vous eu la possibilité de déposer un rapport de bogue?
dreftymac
8

Pour les situations où la chaîne peut contenir des espaces ou non, je préfère les guillemets doubles et la continuation de ligne avec des barres obliques inverses:

key: "String \
  with long c\
  ontent"

Mais notez l'écueil pour le cas où une ligne de continuation commence par un espace, elle doit être échappée (car elle sera supprimée ailleurs):

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

Si la chaîne contient des sauts de ligne, cela doit être écrit dans le style C \n.

Voir aussi cette question .

Joe
la source
Si elle est supprimée ailleurs , c'est-à-dire pas dans cette position, pouvez-vous mettre à jour votre réponse avec des informations sur l' endroit où elle sera supprimée. Veuillez également écrire quel analyseur (pour quelle langue) cela? Je n'ai vu que des analyseurs supprimer ces espaces de début / fin dans les chaînes de guillemets multilignes en place .
Anthon
0

Aucune des solutions ci-dessus n'a fonctionné pour moi, dans un fichier YAML dans un projet Jekyll. Après avoir essayé de nombreuses options, je me suis rendu compte qu'une injection HTML avec <br>pourrait faire aussi bien, car au final tout est rendu en HTML:

nom: | Dans un village de La Mancha <br>dont je ne <br>veux pas me souvenir du nom.

Au moins ça marche pour moi. Aucune idée sur les problèmes liés à cette approche.

Irene
la source
2
Votre solution fait référence à un problème différent: dans votre cas, vous souhaitez que les sauts de ligne apparaissent en HTML rendu à la suite du traitement YAML. HTML et YAML n'ont pas de relation implicite l'un avec l'autre. Et même si YAML passait des sauts de ligne réguliers, HTML les ignorerait. Finalement, la question de l'op est liée à l'utilisation des sauts de ligne dans YAML lui-même juste pour éviter les lignes très longues. Il ne se soucie pas de la façon dont les données pourraient être rendues à la fin. Pourquoi dire ça? Parce que cela explique pourquoi toutes les autres solutions présentées ici ne fonctionnent pas dans votre cas.
Thomas Urban