¿Cómo divido una cadena en varias líneas?


1539

En YAML, tengo una cadena que es muy larga. Quiero mantener esto dentro de la vista de 80 columnas (más o menos) de mi editor, por lo que me gustaría romper la cadena. ¿Cuál es la sintaxis para esto?

En otras palabras, tengo esto:

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

y me gustaría tener esto (o algo por el estilo):

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

Me gustaría usar comillas como las anteriores, por lo que no necesito escapar de nada dentro de la cadena.

Respuestas:


979

Usando el estilo plegado yaml, cada salto de línea se reemplaza por un espacio. La sangría en cada línea será ignorada. Se insertará un salto de línea al 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

Puede usar el "indicador de bloqueo de bloques" para eliminar el salto de línea final, de la siguiente manera:

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.

También hay otras herramientas de control disponibles (para controlar la sangría, por ejemplo).

Ver https://yaml-multiline.info/


Gracias, pero parece que no puede ajustar esta sintaxis entre comillas: las comillas aparecen como literales en la cadena resultante.
jjkparker

De alguna manera, se agrega un retorno de carro justo después del final de la traducción en mi aplicación. De esta forma, Javascript lo ve como varias líneas y falla. {{- 'key'|trans -}}tampoco funciona
Rvanlaak

¿Cómo obtendrías este mismo efecto como un valor en una lista?
Mikhail

cada salto de línea se reemplaza por un espacio o simplemente se elimina?
Steve

2
cada salto de línea se reemplaza por un espacio <- pero un salto de línea doble será un salto de línea.
Jean Jordaan

3355

Hay 5 6 NUEVE (o 63 *, dependiendo de cómo cuente) diferentes formas de escribir cadenas de varias líneas en YAML.

TL; DR

  • Por lo general, quieres >:

    key: >
      Your long
      string here.
    
  • Si desea que los saltos de línea se conserven como \nen la cadena (por ejemplo, marcado incrustado con párrafos), use |.

    key: |
      ### Heading
    
      * Bullet
      * Points
    
  • Use >-o |-en su lugar si no desea que se agregue un salto de línea al final.

  • Si necesita dividir líneas en el medio de las palabras o literalmente escribir saltos de línea como \n, use comillas dobles en su lugar:

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

Bloquear estilos escalares ( >, |)

Estos permiten caracteres como \y "sin escapar, y agregan una nueva línea ( \n) al final de su cadena.

> El estilo plegado elimina las nuevas líneas individuales dentro de la cadena (pero agrega una al final y convierte las nuevas líneas dobles en simples):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

| El estilo literal convierte cada nueva línea dentro de la cadena en una nueva línea literal y agrega una al final:

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

Aquí está la definición oficial de la especificación YAML 1.2

El contenido escalar se puede escribir en notación de bloque, utilizando un estilo literal (indicado por "|") donde todos los saltos de línea son significativos. Alternativamente, se pueden escribir con el estilo plegado (denotado por ">") donde cada salto de línea se pliega en un espacio a menos que termine una línea vacía o más sangría.

Estilos de molde con el indicador masticando bloque ( >-, |-, >+, |+)

Puede controlar el manejo de la nueva línea final en la cadena, y cualquier línea en blanco final ( \n\n) agregando un carácter indicador de bloqueo de bloques :

  • >, |: "clip": mantenga el avance de línea, elimine las líneas en blanco al final.
  • >-, |-: "strip": elimina el avance de línea, elimina las líneas en blanco finales.
  • >+, |+: "keep": mantiene el avance de línea, sigue las líneas en blanco.

"Flujo" estilos escalares ( , ", ')

Estos tienen escapes limitados y construyen una cadena de una sola línea sin nuevos caracteres de línea. Pueden comenzar en la misma línea que la tecla, o con nuevas líneas adicionales primero.

estilo simple (sin escape, sincombinaciones#osin:límites, en el primer carácter):

Key: this is my very very very 
  long string

estilo entre comillas dobles (\y"debe\evitarse, las líneas nuevas se pueden insertar con una\nsecuencialiteral, las líneas se pueden concatenar sin espacios con el 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 entre comillas simples (el literal'debe duplicarse, sin caracteres especiales, posiblemente útil para expresar cadenas que comiencen con comillas dobles):

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

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

Resumen

En esta tabla, _significa space character. \nsignifica "carácter de línea nueva" ( \nen JavaScript), a excepción de la fila "líneas nuevas en línea", donde significa literalmente una barra diagonal inversa y 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       |

Ejemplos

Tenga en cuenta los espacios finales en la línea antes de "espacios".

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

Bloquear estilos con indicadores de sangría

En caso de que lo anterior no sea suficiente para usted, puede agregar un " indicador de sangría de bloque " (después de su indicador de bloqueo de bloque, si tiene uno):

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

Apéndice

Si inserta espacios adicionales al comienzo de las primeras líneas en estilo Doblado, se mantendrán, con una nueva línea de bonificación. Esto no sucede con los estilos de flujo:

- >
    my long
      string
- my long
    string

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

Ni siquiera puedo.

*2 estilos de bloque, cada uno con 2 posibles indicadores de bloqueo de bloque (o ninguno), y con 9 posibles indicadores de sangría (o ninguno), 1 estilo simple y 2 estilos entre comillas: 2 x (2 + 1) x (9 + 1) + 1 + 2 = 63

Parte de esta información también se ha resumido aquí .


28
Entre las 63 sintaxis, ¿cree que hay una sola que le permite deletrear en varias líneas una cadena que no debería tener líneas nuevas ni espacios? Me refiero a lo que uno escribiría "..." + "..."en la mayoría de los lenguajes de programación, o barra diagonal inversa antes de la nueva línea en Bash.
Tobia

23
@pepoluan Probé todas las combinaciones posibles y encontré solo una que permite la concatenación sin espacios: poner comillas dobles alrededor de la cadena y una barra diagonal inversa antes de la nueva línea (y sangría). Ejemplo: datos: texto / plano; base64, dGVzdDogImZvb1wKICBiYXIiCg ==
Tobia

42
@wvxvw, por el contrario, creo que YAML es el peor formato para muchos casos de uso comunes (p. ej., archivos de configuración), sobre todo porque la aparente simplicidad de la mayoría de las personas se siente atraída solo para darse cuenta mucho más tarde de que es un formato extremadamente complejo. YAML hace que las cosas incorrectas se vean bien; por ejemplo, un colon inocuo :dentro de una cadena en una matriz de cadenas hace que YAML lo interprete como una matriz de objetos. Viola el principio del menor asombro .
Vicky Chijwani

20
Alguien creó un sitio web sobre este tema: yaml-multiline.info @SteveBennett ㄹ En caso de que no lo supiera, consulte el pie de página de esa página.
udondan

38
Otra sintaxis de cadena
multilínea

186

Para preservar el uso de líneas nuevas| , por ejemplo:

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

se traduce a "Esta es una oración muy larga‌ \ n que abarca varias líneas en YAML‌ \ n pero que se representará como una cadena‌ \ n con líneas nuevas preservadas. \ n "


¿Esto parece funcionar bien para mí con dos líneas pero no con tres?
cboettig

Gracias, funciona bien allí como dices. Por alguna razón en los encabezados yaml de Pandoc, necesito repetir el |en cada línea, por razones que no me resultan obvias: groups.google.com/forum/#!topic/pandoc-discuss/xuqEmhWgf9A
cboettig

1
¡Este ejemplo NO convierte a nuevas líneas en los carriles 4!
Rubytastic

No es un problema el hecho de que si escribo: - campo1: | uno dos - campo1: | tres para 'I get: one \ ntwo \ ny three \ nfor? Aspecto del \ n después de 2 para no estar allí ...
Alain1405

Cuando se usa multilínea catcon delimitador, esto hace que se agreguen espacios iniciales (que son necesarios para YAML) a la salida.
Karl Richter

110

1. Notación de bloque (simple, estilo de flujo, escalar): las nuevas líneas se convierten en espacios y nuevas líneas adicionales después de eliminar el bloque

---
# 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 de bloque literal: un escalar de bloque literal |incluirá las nuevas líneas y los espacios finales. pero elimina extra

nuevas líneas después del bloque.

---
# 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 con Escalar de bloque literal: mantenga nuevas líneas adicionales después del bloqueo

---
# 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 con Escalar de bloque literal: - significa que se elimina la nueva línea al final de la cadena.

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


...

JSON equivalente

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

5. Escalar de bloque plegado (>):

plegará nuevas líneas a espacios y eliminará nuevas líneas adicionales después del bloque.

---
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 más puedes visitar mi Blog


¿Pretendía, por ejemplo, # 4 usar "| -" después de los dos puntos? Además, aquí puede perder los marcadores finales de las directivas "---", ya que solo muestra un documento. Los marcadores finales del documento son útiles para resaltar el espacio en blanco al final de los documentos. Aparte de eso, sin embargo, no hay necesidad de documentos explícitos.
seh

gracias por señalar eso fue un error tipográfico. A lo he arreglado. He proporcionado un marcador inicial y final para que todos puedan ver nuevas líneas después de la cadena.
Arayan Singh

Nr.1 se describe como un escalar simple de estilo de flujo en la especificación YAML. Llamarlo estilo bloque es engañoso.
Anthon

Cambia Nr.1 ​​como un simple, estilo de flujo, escalar.
Arayan Singh

42

Puede que no lo creas, pero YAML también puede hacer teclas de varias líneas:

?
 >
 multi
 line
 key
:
  value

3
Explicación necesaria (¿qué es "?").
ilyaigpetrov

@ilyaigpetrov exactamente como está escrito, clave "multilínea". Por lo general, hace cosas como key:value, pero si su clave contiene nueva línea, puede hacerlo como se describió anteriormente
goFrendiAsgard el

44
¿Algún ejemplo de un caso de uso del mundo real para esto?
Richard-Degenne

1
@ilyaigpetrov ?es el indicador clave (como en la clave de una asignación). En muchas situaciones, puede omitir el indicador clave, cuando el indicador de valor (requerido) :después de la clave hace que el análisis no sea ambiguo. Pero ese no es el caso, tendrá que usar esto para marcar explícitamente la clave.
Anthon

42

Para concatenar líneas largas sin espacios en blanco , use comillas dobles y escape de las líneas nuevas con barras invertidas:

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

(Gracias @Tobia)


¡Gracias, esto realmente me ayudó a definir los volúmenes de Docker en varias líneas! Si alguien tiene el mismo problema, aquí está mi solución en un analizador de YAML en línea
Mike Mitterer el

Ah por fin. Intenté envolver las teclas ssh largas en los archivos Hiera yaml de Puppet en varias líneas, pero siempre obtuve espacios no deseados hasta que usé su respuesta. Gracias.
Martijn Heemels

18

En caso de que esté usando YAML y Twig para traducciones en Symfony, y quiera usar traducciones de varias líneas en Javascript, se agrega un retorno de carro justo después de la traducción. Entonces, incluso el siguiente código:

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

Que tiene la siguiente traducción yml:

key: >
    This is a
    multi line 
    translation.

Seguirá dando como resultado el siguiente código en html:

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

Entonces, el signo menos en Twig no resuelve esto. La solución es agregar este signo menos después del signo mayor que en yml:

key: >-
    This is a
    multi line 
    translation.

Tendrá el resultado adecuado, traducción de varias líneas en una línea en Twig:

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

Esto parece un error. ¿Tuviste la oportunidad de presentar un informe de error?
dreftymac

8

Para situaciones en las que la cadena puede contener espacios o no, prefiero las comillas dobles y la continuación de línea con barras invertidas:

key: "String \
  with long c\
  ontent"

Pero tenga en cuenta sobre el peligro para el caso de que una línea de continuación comienza con un espacio, debe escaparse (porque se eliminará en otro lugar):

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

Si la cadena contiene saltos de línea, esto debe escribirse en estilo C \n .

Ver también esta pregunta .


Si se elimina en otro lugar , es decir, no en esa posición, ¿puede actualizar su respuesta con información sobre dónde se eliminará? Por favor, escriba también qué analizador (para qué idioma) hace eso? Solo he visto analizadores que eliminan dichos espacios iniciales / finales en cadenas de comillas multilínea en su lugar .
Anthon

0

Ninguna de las soluciones anteriores funcionó para mí, en un archivo YAML dentro de un proyecto Jekyll. Después de probar muchas opciones, me di cuenta de que una inyección HTML con<br> podría funcionar, ya que al final todo se procesa en HTML:

nombre: | en un pueblo de La Mancha <br>cuyo nombre no sé<br> quiero recordar.

Al menos me funciona. No tengo idea de los problemas asociados a este enfoque.


2
Su solución se refiere a un problema diferente: en su caso, desea que aparezcan saltos de línea en HTML representado como resultado del procesamiento de YAML. HTML y YAML no tienen una relación implícita entre sí. E incluso si YAML pasara saltos de línea regulares, HTML los ignoraría. Finalmente, la pregunta del operador está relacionada con el uso de saltos de línea en el propio YAML solo para evitar líneas muy largas. No le importa cómo se podrían representar los datos al final. ¿Por qué decir esto? Porque esto explica por qué todas las otras soluciones dadas aquí no funcionan en su caso.
Thomas Urban
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.