Как разбить строку на несколько строк?

1539

В YAML у меня есть очень длинная строка. Я хочу сохранить это в 80-колоночном (или около того) виде моего редактора, поэтому я хотел бы разбить строку. Какой синтаксис для этого?

Другими словами, у меня есть это:

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

и я хотел бы иметь это (или что-то на этот счет):

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

Я хотел бы использовать кавычки, как указано выше, поэтому мне не нужно ничего экранировать внутри строки.

jjkparker
источник

Ответы:

979

Используя стиль сгиба yaml, каждый разрыв строки заменяется пробелом. Отступ в каждой строке будет игнорироваться. В конце будет вставлен разрыв строки.

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

Вы можете использовать «индикатор блокировки блока», чтобы устранить разрыв в трейлинговой линии следующим образом:

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.

Также доступны другие инструменты управления (например, для управления отступами).

Смотрите https://yaml-multiline.info/

Мэтт Уильямсон
источник
Спасибо, но вы не можете заключить этот синтаксис в кавычки, кажется: кавычки появляются в виде литералов в результирующей строке.
jjkparker
Каким-то образом возврат каретки добавляется сразу после окончания перевода в моем приложении. Таким образом, Javascript видит его как несколько строк и терпит неудачу. {{- 'key'|trans -}}тоже не работает.
Рванлаак
Как бы вы получили такой же эффект, как значение в списке?
Михаил
каждый разрыв строки заменяется пробелом или просто удаляется?
Стив
2
каждый разрыв строки заменяется пробелом <- но разрыв строки будет разрывом строки.
Жан Джордаан
3356

Существует 5 6 NINE (или 63 *, в зависимости от того, как вы считаете) различных способов написания многострочных строк в YAML.

TL; DR

  • Обычно вы хотите >:

    key: >
      Your long
      string here.
    
  • Если вы хотите, чтобы разрывы \nстрок были сохранены, как в строке (например, встроенная разметка с абзацами), используйте |.

    key: |
      ### Heading
    
      * Bullet
      * Points
    
  • Используйте >-или |-вместо этого, если вы не хотите, чтобы разрыв строки добавлялся в конце.

  • Если вам нужно разбить строки в середине слов или буквально ввести перевод строки как \n, используйте вместо этого двойные кавычки:

    key: "Antidisestab\
     lishmentarianism.\n\nGet on it."
    
  • YAML сумасшедший

Блокировать скалярные стили ( >, |)

Они позволяют такие символы, как \и "без экранирования, и добавляют новую строку ( \n) в конец вашей строки.

> Сложенный стиль удаляет одиночные новые строки в строке (но добавляет один в конце и преобразует двойные строки в одиночные):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

| Литеральный стиль превращает каждую новую строку в строке в буквальную новую строку и добавляет один в конце:

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

Вот официальное определение от YAML Spec 1.2

Скалярное содержимое может быть записано в блочной нотации, используя буквальный стиль (обозначенный «|»), где все разрывы строк являются значительными. В качестве альтернативы, они могут быть записаны в сложенном стиле (обозначается «>»), где каждый разрыв строки свернут в пробел, если он не заканчивается пустой или более отступой строкой.

Блок стилей с индикатором блока чавканье ( >-, |-, >+, |+)

Вы можете управлять обработкой последней новой строки в строке и любых завершающих пустых строк ( \n\n), добавив символ индикатора разбиения на блоки :

  • >, |: "clip": сохранить перевод строки, удалить завершающие пустые строки.
  • >-, |-: "strip": удалить перевод строки, удалить завершающие пустые строки.
  • >+, |+: "keep": сохранить перевод строки, оставить после себя пустые строки.

"Поток" стили скалярные ( , ", ')

Они имеют ограниченный выход и создают однострочную строку без символов новой строки. Они могут начинаться с той же строки, что и ключ, или сначала с новых строк.

простой стиль (нет выхода, нет# или: комбинаций, ограничения на первый символ):

Key: this is my very very very 
  long string

стиль в двойных кавычках (\и"должен быть экранирован\, символы новой строки могут быть вставлены с литералом\n последовательностью, строки могут быть объединены без пробелов с завершающими \):

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

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

стиль в одинарных кавычках (буквальный' с одинарными кавычками должен быть удвоен, без специальных символов, возможно, полезно для выражения строк, начинающихся с двойных кавычек):

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

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

Резюме

В этой таблице, _значит space character. \nозначает «символ новой строки» ( \nв JavaScript), за исключением строки «строка новой строки», где это означает буквально обратную косую черту и 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       |

Примеры

Обратите внимание на конечные пробелы в строке перед «пробелами».

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

Стили блоков с индикаторами отступов

На случай, если вышеперечисленного недостаточно для вас, вы можете добавить « индикатор отступа блока » (после индикатора блокирования блока, если он у вас есть):

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

добавление

Если вы вставите лишние пробелы в начале не первых строк в стиле «Сложенный», они будут сохранены с бонусной новой строкой. Этого не происходит со стилями потока:

- >
    my long
      string
- my long
    string

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

Я даже не могу.

*2 стиля блока, каждый с 2-мя возможными индикаторами сочетания блоков (или без них) и с 9-ю возможными индикаторами отступа (или без него), 1 простой стиль и 2 указанных стиля: 2 x (2 + 1) x (9 + 1) + 1 + 2 = 63

Часть этой информации также была обобщена здесь .

Стив Беннетт
источник
28
Как вы думаете, из 63 синтаксисов есть один, который позволяет вам записать в несколько строк строку, в которой не должно быть ни новой строки, ни пробелов? Я имею в виду то, что можно написать, как "..." + "..."в большинстве языков программирования, или обратную косую черту перед новой строкой в ​​Bash.
Тобия
23
@pepoluan Я перепробовал каждую возможную комбинацию и нашел только одну, которая допускает конкатенацию без пробелов: поместите двойные кавычки вокруг строки и обратную косую черту перед новой строкой (и отступом). Пример: data: text / plain; base64, dGVzdDogImZvb1wKICBiYXIiCg ==
Tobia
42
@wvxvw, напротив, я думаю, что YAML - худший формат для многих распространенных сценариев использования (например, конфигурационных файлов), не в последнюю очередь потому, что большинство людей привлекают его очевидной простотой, только чтобы гораздо позже понять, что это чрезвычайно сложный формат. YAML заставляет неправильные вещи выглядеть правильно - например, безобидное двоеточие в :пределах одной строки в массиве строк заставляет YAML интерпретировать его как массив объектов. Это нарушает принцип наименьшего удивления .
Вики Чиджвани
20
Кто-то создал веб-сайт на эту тему: yaml-multiline.info @SteveBennett ㄹ Если вы не знали, проверьте нижний колонтитул этой страницы.
Удондан
38
Еще один многострочный синтаксис строки
xdhmoore
186

Для сохранения перевода строки используйте |, например:

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

переводится как «Это очень длинное предложение‌ \ n, которое занимает несколько строк в YAML‌ \ n, но которое будет отображаться как строка‌ \ n с сохранением новых строк. \ n »

Али Шакиба
источник
Кажется, это нормально работает с двумя строками, а не с тремя?
cboettig
Спасибо, там отлично работает, как вы говорите. По какой-то причине в заголовках yaml Пандока мне нужно повторять их в |каждой строке, по причинам, которые мне не очевидны: groups.google.com/forum/#!topic/pandoc-discuss/xuqEmhWgf9A
cboettig
1
Этот пример НЕ конвертируется в новые строки в rails 4!
Rubytastic
Не проблема в том, что если я напишу: - field1: | один два - field1: | три для 'я получаю: один \ ntwo \ n и три \ nfor? Я хотел бы
аспектировать
При использовании многострочного catс разделителем это приводит к добавлению начальных пробелов (которые необходимы для YAML) к выводу.
Карл Рихтер
110

1. Блок-нотация (обычная, в стиле потока, скалярная): переводы строки становятся пробелами, а дополнительные строки после удаления блока

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

...

Эквивалент JSON

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

2. Буквальный Скалярный Блок: Буквальный Скалярный Блок |будет включать переводы строки и любые пробелы. но удаляет лишнее

новые строки после блока.

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


...

Эквивалент JSON

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

3. + индикатор со скалярным литеральным блоком: сохраняйте дополнительные символы новой строки после блока

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


...

Эквивалент JSON

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

4. - индикатор со скалярным литеральным блоком: - означает, что новая строка в конце строки удалена.

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


...

Эквивалент JSON

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

5. Сложенный блок скаляров (>):

будет складывать новые строки в пробелы, но удаляет лишние новые строки после блока.

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


...

Эквивалент JSON

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

для большего вы можете посетить мой блог

Арайан Сингх
источник
Вы намеревались, например, # 4 использовать «| -» после двоеточия? Кроме того, здесь вы можете потерять маркеры конца директив "---", так как вы показываете только один документ. Маркеры конца документа полезны для выделения конечных пробелов в документах. Кроме того, нет необходимости в явных документах.
SEH
спасибо за указание. это была опечатка. А исправили это. Я предоставил маркер начала и конца, чтобы каждый мог видеть новые строки после строки.
Арайан Сингх
Nr.1 описывается как простой скаляр в стиле потока в спецификации YAML. Называть это блочным стилем вводит в заблуждение.
Anthon
Изменяет Nr.1 ​​как простой скалярный стиль потока.
Арайан Сингх
42

Возможно, вы не поверите, но YAML также может выполнять многострочные ключи:

?
 >
 multi
 line
 key
:
  value
Мохсен
источник
3
Требуется пояснение (что такое "?").
Ильягпетров
@ilyaigpetrov в точности как написано, «многострочный» ключ. Обычно вы делаете такие вещи, как key:value, но если ваш ключ содержит новую строку, вы можете сделать это, как описано выше
goFrendiAsgard
4
Любой пример реального использования для этого?
Ричард-Дегенн
1
@ilyaigpetrov ?является ключевым индикатором (как в ключе в отображении). Во многих ситуациях вы можете не указывать индикатор ключа, когда индикатор (обязательный) значения :после ключа делает разбор однозначным. Но это не тот случай, вам придется использовать это, чтобы явно пометить ключ.
Антон
42

Чтобы объединить длинные строки без пробелов , используйте двойные кавычки и экранируйте символы новой строки с помощью обратной косой черты:

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

(Спасибо @Tobia)

PHS
источник
Спасибо, это действительно помогло мне определить объемы Docker для нескольких строк! Если у кого-то возникла такая же проблема, вот мое решение для онлайнового парсера YAML
Майк Миттерер,
Ах, наконец. Я пытался обернуть длинные ssh-ключи в файлы yaml Hiera в Puppet несколькими строками, но всегда получал ненужные пробелы, пока не использовал ваш ответ. Спасибо.
Мартейн
18

Если вы используете YAML и Twig для переводов в Symfony и хотите использовать многострочные переводы в Javascript, сразу после перевода добавляется возврат каретки. Так что даже следующий код:

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

Который имеет следующий перевод YML:

key: >
    This is a
    multi line 
    translation.

По-прежнему приведет к следующему коду в HTML:

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

Таким образом, знак минус в Twig не решает эту проблему. Решение состоит в том, чтобы добавить этот знак минус после знака «больше, чем» в yml:

key: >-
    This is a
    multi line 
    translation.

Будет ли правильный результат, многострочный перевод в одну строку в Twig:

var javascriptVariable = "This is a multi line translation.";
Rvanlaak
источник
Это похоже на ошибку. У вас была возможность подать отчет об ошибке?
dreftymac
8

Для ситуаций, когда строка может содержать пробелы или нет, я предпочитаю двойные кавычки и продолжение строки с обратными слешами:

key: "String \
  with long c\
  ontent"

Но обратите внимание на ловушку для случая, когда линия продолжения начинается с пробела, ее нужно экранировать (потому что она будет удалена в другом месте):

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

Если строка содержит разрывы строк, это должно быть написано в стиле C \n.

Смотрите также этот вопрос .

Джо
источник
Если он удален в другом месте , то есть не в той позиции, вы можете обновить свой ответ информацией о том, где он будет удален. Пожалуйста, также напишите, какой парсер (для какого языка) это делает? Я только видел парсеры полосы такие ведущие / конечные пробелы в многострочные кавычки строк в месте .
Anthon
0

Ни одно из перечисленных выше решений не сработало для меня в файле YAML в проекте Jekyll. Перепробовав много вариантов, я понял, что HTML-инъекция с использованием <br>может также подойти, так как в итоге все отображается в HTML:

Имя: | В деревне Ла-Манча, <br>чье имя я не <br>хочу помнить.

По крайней мере, это работает для меня. Без понятия о проблемах, связанных с этим подходом.

Ирэн
источник
2
Ваше решение относится к другой проблеме: в вашем случае вы хотите, чтобы в визуализированном HTML разрывы строк появлялись в результате обработки YAML. HTML и YAML не имеют неявных отношений друг с другом. И даже если бы YAML передавал обычные разрывы строк, HTML игнорировал бы их. В конце концов, вопрос о работе связан с использованием разрывов строк в самом YAML просто для предотвращения очень длинных строк. Это не заботится о том, как данные могут быть представлены в конце. Зачем это говорить? Потому что это объясняет, почему все остальные решения, приведенные здесь, не работают в вашем случае.
Томас Урбан