Bagaimana cara memutus string pada beberapa baris?

1539

Di YAML, saya punya string yang sangat panjang. Saya ingin menyimpan ini dalam tampilan 80-kolom (atau lebih) dari editor saya, jadi saya ingin memutus string. Apa sintaks untuk ini?

Dengan kata lain, saya punya ini:

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

Dan saya ingin ini (atau sesuatu seperti ini):

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

Saya ingin menggunakan tanda kutip seperti di atas, jadi saya tidak perlu melarikan diri apa pun dalam string.

jjkparker
sumber

Jawaban:

979

Menggunakan gaya lipat yaml, setiap jeda baris diganti dengan spasi. Lekukan di setiap baris akan diabaikan. Garis putus akan dimasukkan di akhir.

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

Anda dapat menggunakan "block chomping indicator" untuk menghilangkan jeda trailing line, sebagai berikut:

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.

Ada alat kontrol lain yang tersedia juga (untuk mengendalikan indentasi misalnya).

Lihat https://yaml-multiline.info/

Matt Williamson
sumber
Terima kasih, tetapi Anda tidak dapat membungkus sintaks ini dalam tanda kutip, tampaknya: tanda kutip muncul sebagai literal dalam string yang dihasilkan.
jjkparker
Entah bagaimana pengembalian carriage ditambahkan tepat setelah akhir terjemahan di aplikasi saya. Dengan begitu Javascript melihatnya sebagai beberapa baris dan gagal. {{- 'key'|trans -}}juga tidak bekerja.
Rvanlaak
Bagaimana Anda mendapatkan efek yang sama dengan nilai dalam daftar?
Mikhail
setiap jeda baris diganti dengan spasi atau hanya dihapus?
Steve
2
setiap jeda baris diganti dengan spasi <- tetapi jeda baris ganda akan menjadi jeda baris.
Jean Jordaan
3354

Ada 5 6 SEMBILAN (atau 63 *, tergantung bagaimana Anda menghitung) berbagai cara untuk menulis string multi-line dalam YAML.

TL; DR

  • Biasanya, Anda ingin >:

    key: >
      Your long
      string here.
    
  • Jika Anda ingin linebreak dipertahankan seperti \npada string (misalnya, penurunan harga dengan paragraf), gunakan |.

    key: |
      ### Heading
    
      * Bullet
      * Points
    
  • Gunakan >-atau |-sebagai gantinya jika Anda tidak ingin linebreak ditambahkan pada bagian akhir.

  • Jika Anda perlu memecah garis di tengah kata atau mengetik linebreaks secara harfiah \n, gunakan tanda kutip ganda sebagai gantinya:

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

Blokir gaya skalar ( >, |)

Ini memungkinkan karakter seperti \dan "tanpa melarikan diri, dan menambahkan baris baru ( \n) ke akhir string Anda.

> Gaya yang dilipat menghapus baris baru dalam string (tetapi menambahkan satu di akhir, dan mengubah baris ganda menjadi tunggal):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

| Gaya literal mengubah setiap baris baru dalam string menjadi baris baru literal, dan menambahkan satu di akhir:

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

Berikut definisi resmi dari YAML Spec 1.2

Konten skalar dapat ditulis dalam notasi blok, menggunakan gaya literal (ditunjukkan oleh "|") di mana semua jeda baris signifikan. Atau, mereka dapat ditulis dengan gaya terlipat (dilambangkan dengan ">") di mana setiap garis putus dilipat ke suatu ruang kecuali itu berakhir dengan baris yang kosong atau lebih berlekuk.

Blok gaya dengan indikator mengunyah blok ( >-, |-, >+, |+)

Anda dapat mengontrol penanganan baris baru akhir dalam string, dan setiap garis kosong trailing ( \n\n) dengan menambahkan karakter blok pengejar :

  • >, |: "clip": pertahankan feed baris, hapus baris trailing blank.
  • >-, |-: "strip": hapus feed baris, hapus baris kosong yang tertinggal.
  • >+, |+: "keep": pertahankan feed baris, tetap ikuti baris kosong.

"Arus" gaya skalar ( , ", ')

Ini memiliki pelarian yang terbatas, dan membuat string baris tunggal tanpa karakter baris baru. Mereka dapat mulai pada baris yang sama dengan kunci, atau dengan baris baru tambahan terlebih dahulu.

gaya polos (tidak ada pelarian, tidak ada#atau:kombinasi, batas karakter pertama):

Key: this is my very very very 
  long string

gaya kutipan ganda (\dan"harus diloloskan oleh\, baris baru dapat disisipkan dengan\nurutanliteral, garis dapat digabungkan tanpa spasi dengan trailing\):

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

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

gaya kutipan tunggal (literal'harus digandakan, tidak ada karakter khusus, mungkin berguna untuk mengekspresikan string yang dimulai dengan tanda kutip ganda):

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

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

Ringkasan

Dalam tabel ini, _berarti space character. \nberarti "karakter baris baru" ( \ndalam JavaScript), kecuali untuk baris "baris baru in-line", di mana secara harfiah berarti garis miring terbalik dan 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       |

Contohnya

Perhatikan spasi tambahan pada baris sebelum "spasi".

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

Blokir gaya dengan indikator lekukan

Untuk berjaga-jaga jika hal di atas tidak cukup untuk Anda, Anda dapat menambahkan " indikator indentasi blok " (setelah indikator blok pengompakan, jika ada):

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

Tambahan

Jika Anda memasukkan spasi tambahan di awal baris yang tidak pertama dalam gaya Dilipat, mereka akan disimpan, dengan bonus baris baru. Ini tidak terjadi dengan aliran gaya:

- >
    my long
      string
- my long
    string

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

Saya tidak bisa.

*2 gaya blok, masing-masing dengan 2 indikator blok chomping (atau tidak ada), dan dengan 9 indikator indentasi yang mungkin (atau tidak ada), 1 gaya polos dan 2 gaya kutipan: 2 x (2 + 1) x (9 + 1) + 1 + 2 = 63

Beberapa informasi ini juga telah dirangkum di sini .

Steve Bennett
sumber
28
Di antara 63 sintaksis, apakah menurut Anda ada satu sintaks yang memungkinkan Anda mengeja dalam beberapa baris string yang seharusnya tidak memiliki baris baru atau spasi? Maksud saya apa yang akan ditulis seperti "..." + "..."dalam kebanyakan bahasa pemrograman, atau garis miring terbalik sebelum baris baru di Bash.
Tobia
23
@pepoluan Saya mencoba setiap kombinasi yang mungkin dan hanya menemukan satu yang memungkinkan untuk penggabungan tanpa spasi: menempatkan tanda kutip ganda di sekitar string dan garis miring terbalik sebelum baris baru (dan lekukan.) Contoh: data: teks / polos; base64, dGVzdDogImZvb1wKICBiYXIiCg ==
Tobia
42
@wvxvw sebaliknya, saya pikir YAML adalah format terburuk untuk banyak kasus penggunaan umum (misalnya, file konfigurasi), paling tidak karena kebanyakan orang tertarik dengan kesederhanaan yang tampak hanya untuk menyadari kemudian bahwa itu format yang sangat kompleks. YAML membuat hal-hal yang salah terlihat benar - misalnya, sebuah usus yang tidak berbahaya :dalam satu string dalam array string membuat YAML mengartikannya sebagai array objek. Itu melanggar prinsip tercengang .
Vicky Chijwani
20
Seseorang membuat situs web tentang topik ini: yaml-multiline.info @SteveBennett ㄹ Jika Anda tidak menyadarinya, periksa footer halaman tersebut.
udondan
38
Namun sintaks string Multi Line Lain
xdhmoore
186

Untuk mempertahankan penggunaan baris baru| , misalnya:

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

diterjemahkan ke "Ini adalah kalimat yang sangat panjang‌ \ n yang mencakup beberapa baris dalam YAML‌ \ n tetapi yang akan diterjemahkan sebagai string‌ \ n dengan baris baru dipertahankan. \ n "

Ali Shakiba
sumber
Ini sepertinya bekerja dengan baik untuk saya dengan dua baris tetapi tidak dengan tiga?
cboettig
Terima kasih, berfungsi dengan baik di sana seperti yang Anda katakan. Untuk beberapa alasan di header yaml Pandoc, saya perlu mengulangi |pada setiap baris, untuk alasan yang tidak jelas bagi saya: groups.google.com/forum/#!topic/pandoc-discuss/xuqEmhWgf9A
cboettig
1
Contoh ini TIDAK dikonversi ke jalur baru di rail 4!
Rubytastic
Bukan masalah fakta bahwa jika saya menulis: - field1: | satu dua - bidang1: | tiga untuk 'Saya dapat: satu \ ndua \ n dan tiga \ nuntuk? Saya akan aspek \ n setelah 2 untuk tidak berada di sana ...
Alain1405
Ketika menggunakan multiline catdengan pembatas, ini menyebabkan spasi terkemuka (yang diperlukan untuk YAML) ditambahkan ke output.
Karl Richter
110

1. Blok Notasi (polos, aliran-gaya, skalar): Baris baru menjadi spasi dan baris baru ekstra setelah blok dihapus

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

...

JSON Setara

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

2. Skalar Blok Sastra: Skalar Blok Sastra | akan mencakup baris baru dan spasi tambahan. tetapi menghapus ekstra

baris baru setelah blok.

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


...

JSON Setara

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

3. + indikator dengan Skalar Blok Sastra: menjaga baris baru ekstra setelah blok

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


...

JSON Setara

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

4. - Indikator dengan Literal Block Scalar: - berarti baris baru pada akhir string dihapus.

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


...

JSON Setara

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

5. Skalar Blok Lipat (>):

akan melipat baris baru ke spasi dan tetapi menghapus baris baru ekstra setelah blok.

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


...

JSON Setara

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

untuk lebih lanjut Anda dapat mengunjungi Blog saya

Arayan Singh
sumber
Apakah Anda bermaksud misalnya # 4 untuk menggunakan "| -" setelah titik dua? Selain itu, Anda dapat kehilangan petunjuk akhir "---" di sini, karena Anda hanya menunjukkan satu dokumen. Penanda akhir dokumen sangat membantu untuk menyoroti spasi spasi tambahan dalam dokumen. Selain itu, tidak perlu dokumen eksplisit.
seh
terima kasih telah menunjukkan. itu salah ketik. A telah memperbaikinya. Saya telah menyediakan penanda awal dan akhir sehingga semua orang dapat melihat baris baru setelah string.
Arayan Singh
Nr.1 dideskripsikan sebagai skalar polos, aliran-gaya, dalam spesifikasi YAML. Menyebutnya gaya blok menyesatkan.
Anthon
Mengubah Nr.1 ​​sebagai skalar polos, aliran-gaya.
Arayan Singh
42

Anda mungkin tidak mempercayainya, tetapi YAML juga dapat melakukan kunci multi-baris:

?
 >
 multi
 line
 key
:
  value
Mohsen
sumber
3
Diperlukan penjelasan (apa itu "?").
ilyaigpetrov
@ilyaigpetrov persis seperti yang tertulis, "multi-line" key. Biasanya Anda melakukan hal-hal seperti key:value, tetapi jika kunci Anda berisi baris baru, Anda dapat melakukannya seperti dijelaskan di atas
goFrendiAsgard
4
Adakah contoh kasus penggunaan dunia nyata untuk ini?
Richard-Degenne
1
@ilyaigpetrov ?adalah indikator kunci (seperti pada kunci dalam pemetaan). Dalam banyak situasi Anda dapat meninggalkan indikator kunci, ketika indikator nilai (diperlukan) :setelah kunci membuat penguraian menjadi tidak ambigu. Tapi bukan itu masalahnya, Anda harus menggunakan ini untuk secara eksplisit menandai kuncinya.
Anthon
42

Untuk menggabungkan garis panjang tanpa spasi , gunakan tanda kutip ganda dan keluar dari baris baru dengan garis miring terbalik:

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

(Terima kasih @Tobia)

phs
sumber
Terima kasih, ini sangat membantu saya untuk menentukan volume Docker di beberapa baris! Jika seseorang memiliki masalah yang sama, berikut adalah solusi saya pada Parser YAML Online
Mike Mitterer
Ah akhirnya. Saya mencoba untuk membungkus ssh-keys panjang dalam file Hiera yaml Puppet di beberapa baris tetapi selalu mendapat ruang yang tidak diinginkan sampai saya menggunakan jawaban Anda. Terima kasih.
Martijn Heemels
18

Jika Anda menggunakan YAML dan Twig untuk terjemahan di Symfony, dan ingin menggunakan terjemahan multi-baris dalam Javascript, carriage return ditambahkan tepat setelah terjemahan. Begitu pun kode berikut:

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

Yang memiliki terjemahan yml berikut:

key: >
    This is a
    multi line 
    translation.

Akan tetap menghasilkan kode berikut dalam html:

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

Jadi, tanda minus pada Ranting tidak menyelesaikan ini. Solusinya adalah menambahkan tanda minus ini setelah tanda lebih besar dari yml:

key: >-
    This is a
    multi line 
    translation.

Akan memiliki hasil yang layak, terjemahan multi-baris pada satu baris di Twig:

var javascriptVariable = "This is a multi line translation.";
Rvanlaak
sumber
Ini terlihat seperti bug. Apakah Anda memiliki kesempatan untuk mengajukan laporan bug?
dreftymac
8

Untuk situasi di mana string mungkin berisi spasi atau tidak, saya lebih suka tanda kutip ganda dan garis kelanjutan dengan garis miring terbalik:

key: "String \
  with long c\
  ontent"

Tetapi perhatikan tentang jebakan untuk kasus bahwa garis kelanjutan dimulai dengan spasi, perlu diloloskan (karena akan dilucuti di tempat lain):

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

Jika string berisi jeda baris, ini perlu ditulis dalam gaya C \n.

Lihat juga pertanyaan ini .

Joe
sumber
Jika itu dilucuti di tempat lain , yaitu tidak dalam posisi itu, dapatkah Anda memperbarui jawaban Anda dengan informasi tentang di mana ia akan dilucuti. Tolong juga tulis pengurai mana (untuk bahasa apa) melakukannya? Saya hanya melihat parser menelanjangi ruang terdepan / tertinggal tersebut dalam string kutipan multiline di tempatnya .
Anthon
0

Tidak ada solusi di atas yang berfungsi untuk saya, dalam file YAML dalam proyek Jekyll. Setelah mencoba banyak opsi, saya menyadari bahwa suntikan HTML dengan <br>mungkin dilakukan juga, karena pada akhirnya semuanya dirender ke HTML:

name: | Di desa La Mancha <br>yang namanya tidak <br>ingin kuingat.

Setidaknya itu bekerja untuk saya. Tidak tahu tentang masalah yang terkait dengan pendekatan ini.

Irene
sumber
2
Solusi Anda mengacu pada masalah yang berbeda: dalam kasus Anda, Anda ingin linebreak muncul dalam HTML yang diberikan sebagai hasil pemrosesan YAML. HTML dan YAML tidak memiliki hubungan implisit satu sama lain. Dan bahkan jika YAML akan melewati linebreak biasa, HTML akan mengabaikannya. Akhirnya pertanyaan op terkait dengan menggunakan linebreak di YAML sendiri hanya untuk mencegah garis yang sangat panjang. Tidak peduli bagaimana data akan ditampilkan pada akhirnya. Kenapa mengatakan ini? Karena ini menjelaskan mengapa semua solusi lain yang diberikan di sini tidak berfungsi untuk Anda.
Thomas Urban