Jak przerwać ciąg w wielu wierszach?


1536

W YAML mam ciąg, który jest bardzo długi. Chcę to zachować w 80-kolumnowym widoku mojego edytora, więc chciałbym przerwać ciąg. Jaka jest składnia tego?

Innymi słowy, mam to:

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

i chciałbym mieć to (lub coś w tym celu):

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

Chciałbym użyć cytatów jak powyżej, więc nie muszę uciekać przed niczym w ciągu.

Odpowiedzi:


976

Używając stylu yaml złożonego, każdy podział linii jest zastępowany spacją. Wcięcie w każdej linii zostanie zignorowane. Podział linii zostanie wstawiony na końcu.

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

Możesz użyć „wskaźnika chompowania bloków”, aby wyeliminować przerwanie linii końcowej w następujący sposób:

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.

Dostępne są również inne narzędzia kontrolne (na przykład do kontrolowania wcięć).

Zobacz https://yaml-multiline.info/


Dzięki, ale nie można zawrzeć tej składni w cudzysłowach: wydaje się, że w wynikowym łańcuchu cudzysłowy pojawiają się jako literały.
jjkparker

Jakoś zwrot karetki jest dodawany bezpośrednio po zakończeniu tłumaczenia w mojej aplikacji. W ten sposób JavaScript widzi to jako wiele wierszy i kończy się niepowodzeniem. {{- 'key'|trans -}}też nie działa.
Rvanlaak,

Jak uzyskasz taki sam efekt jak wartość na liście?
Michaił

każdy podział linii jest zastępowany spacją lub po prostu usuwany?
Steve

2
każdy podział linii jest zastępowany spacją <- ale podwójny podział linii będzie łamaniem linii.
Jean Jordaan,

3349

Istnieje 5 6 Dziewięć (lub 63 *, w zależności od tego, jak się liczy) różnych sposobów pisania ciągów wieloliniowych w YAML.

TL; DR

  • Zwykle chcesz >:

    key: >
      Your long
      string here.
    
  • Jeśli chcesz, aby podziały wierszy były zachowywane jak \nw ciągu (na przykład osadzone znakowanie akapitu), użyj |.

    key: |
      ### Heading
    
      * Bullet
      * Points
    
  • Użyj >-lub |-zamiast tego, jeśli nie chcesz dołączać podziału linii na końcu.

  • Jeśli chcesz podzielić wiersze na środku słów lub dosłownie wpisać podziały wiersza jako \n, użyj podwójnych cudzysłowów:

    key: "Antidisestab\
     lishmentarianism.\n\nGet on it."
    
  • YAML jest szalony.

Blokuj style skalarne ( >, |)

Pozwalają one na znaki takie jak \ i "bez ucieczki oraz dodają nową linię ( \n) na końcu łańcucha.

> Styl zagięty usuwa pojedyncze znaki nowego ciągu (ale dodaje jeden na końcu i konwertuje podwójne znaki nowego na pojedyncze):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

| Dosłowny styl zamienia każdą nową linię w ciągu w dosłowną nową linię i dodaje jedną na końcu:

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

Oto oficjalna definicja z YAML Spec 1.2

Treść skalarną można zapisać w notacji blokowej, używając literalnego stylu (oznaczonego „|”), w którym wszystkie podziały linii są znaczące. Alternatywnie, można je pisać stylem złożonym (oznaczonym jako „>”), w którym każdy podział linii jest składany na spację, chyba że kończy się pusta lub bardziej wcięta linia.

Style bloku z bloku chomping wskaźnik ( >-, |-,>+ , |+)

Możesz kontrolować obsługę ostatniego nowego wiersza w łańcuchu i dowolnych końcowych pustych linii ( \n\n), dodając znak wskaźnika chompingowania bloku :

  • >, | : „clip”: utrzymuj linię, usuń końcowe puste linie.
  • >-, |- : „strip”: usuń linię, usuń końcowe puste linie.
  • >+, |+: „keep”: utrzymuj linię, kontynuuj puste linie.

"Flow" style skalarne ( , ",' )

Mają one ograniczone znaki ucieczki i konstruują łańcuch jednowierszowy bez żadnych nowych znaków linii. Mogą zaczynać się w tym samym wierszu co klawisz lub najpierw z dodatkowymi znakami nowej linii.

zwykły styl (ma ucieczki, nie ma#lub:kombinacje ograniczeń pierwszego znaku):

Key: this is my very very very 
  long string

styl podwójnego cudzysłowu (\i"musi być\poprzedzony znakiemucieczki, znaki nowej linii można wstawiać w dosłownej\nkolejności, linie można łączyć bez spacji z końcowymi znakami\):

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

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

styl pojedynczego cudzysłowu (literał'musi być podwojony, bez znaków specjalnych, być może przydatne do wyrażania ciągów zaczynających się od podwójnych cudzysłowów):

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

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

Podsumowanie

W tej tabeli _oznacza space character. \noznacza „znak nowej linii” ( \nw JavaScript), z wyjątkiem wiersza „wbudowane znaki nowej linii”, gdzie dosłownie oznacza to odwrotny ukośnik i 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       |

Przykłady

Zwróć uwagę na końcowe spacje w wierszu przed „spacjami”.

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

Blokuj style za pomocą wskaźników wcięcia

Na wypadek gdyby powyższe nie było dla Ciebie wystarczające, możesz dodać „ wskaźnik wcięcia bloku ” (po wskaźniku chompingowania bloku, jeśli taki masz):

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

Uzupełnienie

Jeśli wstawisz dodatkowe spacje na początku nie-pierwszych wierszy w stylu zagiętym, zostaną one zachowane z nową linią bonusową. Nie dzieje się tak w przypadku stylów przepływu:

- >
    my long
      string
- my long
    string

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

Nawet nie umiem.

*2 style bloków, każdy z 2 możliwymi wskaźnikami chompowania bloków (lub brak) i 9 możliwymi wskaźnikami wcięcia (lub brak), 1 styl zwykły i 2 stylami cytowanymi: 2 x (2 + 1) x (9 + 1) + 1 + 2 = 63

Niektóre z tych informacji zostały również tutaj streszczone .


28
Czy uważasz, że wśród 63 składni jest jedna, która pozwala przeliterować w wielu wierszach ciąg, który nie powinien zawierać znaków nowej linii ani spacji? Mam na myśli to, co napisalibyśmy "..." + "..."w większości języków programowania lub ukośnik odwrotny przed nową linią w Bash.
Tobia,

23
@poluolu Wypróbowałem każdą możliwą kombinację i znalazłem tylko jedną, która pozwala na łączenie bez spacji: umieść podwójne cudzysłowy wokół łańcucha i odwrotny ukośnik przed znakiem nowej linii (i wcięciem). Przykład: dane: tekst / zwykły; base64, dGVzdDogImZvb1wKICBiYXIiCg ==
Tobia

41
@wvxvw wręcz przeciwnie, uważam, że YAML jest najgorszym formatem dla wielu typowych przypadków użycia (np. plików konfiguracyjnych), zwłaszcza dlatego, że większość ludzi przyciąga jego pozorna prostota, aby zorientować się znacznie później, że jest to niezwykle złożony format. YAML sprawia, że ​​złe rzeczy wyglądają dobrze - na przykład nieszkodliwy dwukropek :w obrębie jednego łańcucha w tablicy łańcuchów powoduje, że YAML interpretuje to jako tablicę obiektów. Narusza to zasadę najmniejszego zdziwienia .
Vicky Chijwani

19
Ktoś utworzył stronę internetową na ten temat: yaml-multiline.info @SteveBennett ㄹ Jeśli nie wiesz, sprawdź stopkę tej strony.
udondan

37
Yet Another Multi Line składnia ciągów
xdhmoore,

186

Aby zachować nowe wiersze, użyj |na przykład:

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

jest tłumaczone na „To jest bardzo długie zdanie‌ \ n, które obejmuje kilka wierszy w YAML‌ \ n, ale które będzie renderowane jako ciąg‌ \ n z zachowanymi znakami nowej linii. \ n


Wydaje mi się, że to działa dobrze z dwiema liniami, ale nie z trzema?
cboettig

Dzięki, działa dobrze, tak jak mówisz. Z jakiegoś powodu w nagłówkach yaml Pandoc muszę powtórzyć| w każdym wierszu, z powodów, które nie są dla mnie oczywiste: groups.google.com/forum/#!topic/pandoc-discuss/xuqEmhWgf9A
cboettig

1
Ten przykład NIE konwertuje na nowe linie w szynach 4!
Rubytastyczny

Nie jest problemem fakt, że jeśli napiszę: - pole1: | jeden dwa - pole1: | trzy za „Dostaję: jeden \ ntwo \ n i trzy \ n za? Chciałbym wziąć pod uwagę \ n po 2, żeby mnie tam nie było ...
Alain1405

W przypadku korzystania catz multilinii z separatorem powoduje to, że do wyniku dodawane są spacje wiodące (niezbędne dla YAML).
Karl Richter

109

1. Notacja bloku (zwykła, płynna, skalarna): nowe linie stają się spacjami i dodatkowe nowe linie po usunięciu bloku

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

...

Odpowiednik JSON

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

2. Dosłowna skalarna blokowa: dosłowna skalarna blokowa |będą zawierać znaki nowej linii i wszelkie spacje końcowe. ale usuwa dodatkowe

nowe linie po bloku.

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


...

Odpowiednik JSON

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

3. + wskaźnik z dosłowną skalą bloku: zachowaj dodatkowe znaki nowej linii po bloku

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


...

Odpowiednik JSON

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

4. - wskaźnik z dosłowną skalą blokową: - oznacza, że ​​nowa linia na końcu łańcucha jest usuwana.

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


...

Odpowiednik JSON

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

5. Skalarny składany blok (>):

będzie składać nowe wiersze do spacji, ale usuwa dodatkowe nowe wiersze po bloku.

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


...

Odpowiednik JSON

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

więcej możesz odwiedzić mój blog


Czy na przykład # 4 używałeś „| -” po dwukropku? Możesz także utracić znaczniki końcowe dyrektyw „---”, ponieważ wyświetlasz tylko jeden dokument. Znaczniki końca dokumentu są pomocne do podkreślenia końcowego odstępu w dokumentach. Poza tym nie ma potrzeby tworzenia jawnych dokumentów.
seh

dzięki za wskazanie. to była literówka. Naprawiłem to. Podałem znacznik początkowy i końcowy, aby każdy mógł zobaczyć nowe wiersze po łańcuchu.
Arayan Singh,

Nr.1 jest opisany jako zwykły skalar w stylu przepływowym w specyfikacji YAML. Nazywanie tego stylem blokowym jest mylące.
Anthon

Zmienia nr 1 jako zwykły, skalarny styl przepływu.
Arayan Singh

42

Możesz w to nie wierzyć, ale YAML może także wykonywać klucze wieloliniowe:

?
 >
 multi
 line
 key
:
  value

3
Konieczne wyjaśnienie (co to jest „?”).
ilyaigpetrov

@ilyaigpetrov dokładnie tak, jak napisano, klawisz „wieloliniowy”. Zwykle robisz takie rzeczy key:value, ale jeśli twój klucz zawiera nową linię, możesz to zrobić jak opisano powyżej
goFrendiAsgard

4
Czy jest na to przykład rzeczywistego przypadku użycia?
Richard-Degenne,

1
@ilyaigpetrov ?jest kluczowym wskaźnikiem (jak w kluczu w mapowaniu). W wielu sytuacjach możesz pominąć wskaźnik klucza, gdy (wymagana) wartość wskaźnika :po kluczu sprawia, że ​​parsowanie jest jednoznaczne. Ale tak nie jest, musisz użyć tego do wyraźnego zaznaczenia klucza.
Anthon

42

Aby połączyć długie linie bez spacji , użyj podwójnych cudzysłowów i unikaj znaków nowej linii za pomocą odwrotnych ukośników:

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

(Dzięki @Tobia)


Dzięki, to naprawdę pomogło mi zdefiniować woluminy dokera w wielu liniach! Jeśli ktoś ma ten sam problem, oto moje rozwiązanie w internetowym parserze YAML
Mike Mitterer

Ach w końcu. Próbowałem zawijać długie klucze ssh w plikach Yaml Puppy Hiera w wielu wierszach, ale zawsze otrzymywałem niechciane spacje, dopóki nie użyłem twojej odpowiedzi. Dzięki.
Martijn Heemels,

18

Jeśli używasz YAML i Twig do tłumaczeń w Symfony i chcesz używać tłumaczeń wieloliniowych w JavaScript, zwrot karetki jest dodawany zaraz po tłumaczeniu. Więc nawet następujący kod:

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

Który ma następujące tłumaczenie yml:

key: >
    This is a
    multi line 
    translation.

Nadal spowoduje powstanie następującego kodu w html:

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

Tak więc znak minus w Twig nie rozwiązuje tego. Rozwiązaniem jest dodanie tego znaku minus po znaku większy niż znak w yml:

key: >-
    This is a
    multi line 
    translation.

Będzie mieć poprawny wynik, tłumaczenie wielu wierszy w jednym wierszu w Twig:

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

To wygląda na błąd. Czy miałeś okazję złożyć raport o błędzie?
dreftymac,

8

W sytuacjach, w których łańcuch może zawierać spacje lub nie, wolę podwójne cudzysłowy i kontynuację wiersza z odwrotnymi ukośnikami:

key: "String \
  with long c\
  ontent"

Ale zwróć uwagę na pułapkę w przypadku, gdy linia kontynuacji zaczyna się od spacji, należy ją uciec (ponieważ zostanie usunięta w innym miejscu):

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

Jeśli ciąg zawiera podziały wiersza, należy to zapisać w stylu C. \n .

Zobacz także to pytanie .


Jeśli zostanie usunięty gdzie indziej , tj. Nie w tej pozycji, czy możesz zaktualizować swoją odpowiedź o informacje o tym, gdzie zostanie on usunięty. Napisz także, który parser (dla jakiego języka) to robi? Mam tylko widziałem Parsery pozbawić takiej wiodącej / końcowe spacje w multilinii notowań strun w miejscu .
Anthon

0

Żadne z powyższych rozwiązań nie działało dla mnie w pliku YAML w ramach projektu Jekyll. Po wypróbowaniu wielu opcji, zdałem sobie sprawę, że wstrzyknięcie HTML<br> może również zrobić, ponieważ ostatecznie wszystko jest renderowane do HTML:

imię: | W wiosce La Mancha, <br>której imienia nie znam<br> chcę pamiętać.

Przynajmniej to działa dla mnie. Nie ma pojęcia o problemach związanych z tym podejściem.


2
Twoje rozwiązanie odnosi się do innego problemu: w twoim przypadku chcesz, aby w renderowanym HTML pojawiały się podziały linii w wyniku przetwarzania YAML. HTML i YAML nie mają ze sobą ukrytych relacji. I nawet jeśli YAML przejdzie regularne łamanie wierszy, HTML je zignoruje. Ostatecznie pytanie op związane jest z użyciem łamania linii w samym YAML, aby zapobiec bardzo długim liniom. Nie ma znaczenia, w jaki sposób dane mogą być renderowane na końcu. Po co to mówić? Ponieważ to wyjaśnia, dlaczego wszystkie inne podane tutaj rozwiązania nie działają w twoim przypadku.
Thomas Urban
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.