String multiline dalam JSON

656

Saya sedang menulis beberapa file data dalam format JSON dan ingin memiliki nilai string yang sangat panjang dibagi menjadi beberapa baris. Menggunakan modul JSON python saya mendapatkan banyak kesalahan, apakah saya menggunakan \atau \nsebagai pelarian.

Apakah mungkin memiliki string multi-line di JSON? Ini sebagian besar untuk kenyamanan visual jadi saya kira saya bisa mengaktifkan bungkus kata di editor saya, tapi saya hanya ingin tahu ...

Anonnobody
sumber
2
Kemungkinan duplikat dari Bagaimana cara menangani baris baru di JSON?
Flimzy
1
susun data Anda: pisahkan string multiline menjadi array string, dan kemudian gabungkan bersama.
RubyTuesdayDONO
2
Coba alat hjson. Ini akan mengubah String multiline Anda di json ke format json yang tepat.
gaurav
Kemungkinan duplikat nilai Can JSON berisi string multiline
Flimzy

Jawaban:

403

JSON tidak mengizinkan jeda baris nyata. Anda harus mengganti semua jeda baris dengan \n.

misalnya:

"first line second line"

dapat disimpan dengan:

"first line\nsecond line"

catatan:

karena Python, ini harus ditulis sebagai:

"first line\\nsecond line"

di mana \\untuk menghindari backslash, jika tidak python akan memperlakukan \nsebagai karakter kontrol "baris baru"

KAMU
sumber
89
-1 OP adalah menggunakan "\ n" urutan escape. Ini tidak berfungsi karena mereka tidak lolos dari garis miring terbalik , seperti "\\ n", jadi Python mengonversi urutan pelarian ke karakter baris baru daripada meninggalkannya secara harfiah garis miring terbalik diikuti oleh en, seperti yang diminta JSON.
user359996
6
@ user359996 Saya tidak yakin itu benar. Bagi saya (menyimpan data dalam JSON hanya dengan \ndan mengeluarkannya melalui Kutukan), \ntampaknya berfungsi dengan baik. Tergantung pada tampilan / rendering engine, tampaknya.
ashes999
2
Urutan baris baru memang khusus untuk platform (lih. En.wikipedia.org/wiki/Newline#Representations ). Namun, per @Lightness Races dalam jawaban Orbit, baik karakter kursor-balik maupun umpan baris tidak ada dalam tata bahasa JSON. Sebenarnya saya bukan programmer Python, jadi saya tidak yakin apa yang terjadi dalam kasus Anda, tetapi apakah parser Anda rusak atau Anda tidak menyampaikannya seperti yang Anda pikirkan. Mungkin jawaban ini menjelaskannya dengan lebih baik: stackoverflow.com/a/9295597/359996 . Perhatikan terutama tentang melarikan diri ganda.
user359996
5
@Nawaz: "\ n" dan "\ r" adalah urutan melarikan diri untuk linefeed dan carriage return, masing-masing. Mereka bukan linefeed dan carriage-return kontrol literal karakter . Sebagai contoh tambahan untuk membuatnya lebih jelas, pertimbangkan bahwa "\\" adalah urutan pelarian untuk backslash, berbeda dengan backslash literal. Tata bahasa JSON secara eksplisit mengecualikan karakter kontrol (lih. Definisi "char"), dan sebagai gantinya menyediakan representasi mereka melalui urutan escape (\\, \ r, \ n, dll.).
user359996
2
@ user359996: Ya .. Saya melihat itu nanti, meskipun saya menyimpan komentar lama saya, kalau-kalau ada orang lain yang memiliki keraguan yang sama, diskusi kita mungkin membantu mereka. terima kasih telah mengkonfirmasinya BTW.
Nawaz
197

Saya harus melakukan ini untuk proyek Node.js kecil dan menemukan ini berhasil :

{
 "modify_head": [

  "<script type='text/javascript'>",
  "<!--",
  "  function drawSomeText(id) {",
  "  var pjs = Processing.getInstanceById(id);",
  "  var text = document.getElementById('inputtext').value;",
  "  pjs.drawText(text);}",
  "-->",
  "</script>"

 ],

 "modify_body": [

  "<input type='text' id='inputtext'></input>",
  "<button onclick=drawSomeText('ExampleCanvas')></button>"

 ],
}

Ini terlihat sangat rapi bagi saya, mulai dari itu saya harus menggunakan tanda kutip ganda di mana-mana. Meskipun sebaliknya, saya bisa, mungkin, menggunakan YAML, tetapi yang memiliki jebakan lain dan tidak didukung secara native. Setelah diurai, saya hanya menggunakan myData.modify_head.join('\n')atau myData.modify_head.join(), tergantung pada apakah saya ingin garis putus setelah setiap string atau tidak.

errordeveloper
sumber
40
Ini adalah solusi untuk pengaturan tertentu, tidak harus terkait dengan pertanyaan. Apa yang Anda buat tidak ada string multiline (yang tidak mungkin pula), tetapi array dengan string di dalam
Samuel Rivas
3
Ini menunjukkan cara memasukkan baris baru di string, yang TIDAK menjawab pertanyaan. Jawaban ini benar.
fgrieu
1
fgrieu - orang bisa dengan mudah menggabungkan string tanpa menambahkan baris baru. Dengan perubahan kecil itu, ia menyediakan solusi untuk string multiline (selama Anda mengendalikan menentukan skema JSON). Saya akan mencoba meningkatkan jawabannya dengan ini.
drrob
1
Terima kasih, saya suka ini. Saya akan melakukan ini untuk apa yang saya kerjakan. Itu terlihat rapi dan terorganisir. Saya akan meminta setiap baris baru di array ini menyiratkan garis putus-putus dalam teks yang di-output, meskipun solusi ini juga bisa berfungsi untuk kasus-kasus di mana Anda tidak menyisipkan jeda baris. Saya telah menggunakan solusi ini sebelumnya dalam kode sumber javascript saya hanya karena saya suka bagaimana terorganisir kelihatannya dan bagaimana tidak meninggalkan keraguan seperti apa ruang putih masuk ke string terakhir.
Gal
Meskipun reservasi penemu JSON, saya hanya menggunakan ini untuk menambahkan komentar (tanpa bagian javascript, tetapi hanya [] dan koma) untuk menambahkan komentar untuk membantu calon pengelola di masa depan yang mungkin mengedit tangan file JSON kecil saya.
Whirl Mind
117

Sayangnya banyak jawaban di sini menjawab pertanyaan tentang bagaimana cara menempatkan karakter baris baru dalam data string. Pertanyaannya adalah bagaimana membuat kode terlihat lebih bagus dengan memisahkan nilai string di beberapa baris kode. (Dan bahkan jawaban yang mengenali ini memberikan "solusi" yang berasumsi seseorang bebas untuk mengubah representasi data, yang dalam banyak kasus tidak.)

Dan berita buruknya adalah, tidak ada jawaban yang bagus.

Dalam banyak bahasa pemrograman, bahkan jika mereka tidak secara eksplisit mendukung pemisahan string di seluruh baris, Anda masih dapat menggunakan penggabungan string untuk mendapatkan efek yang diinginkan; dan selama kompilernya tidak buruk, ini bagus.

Tetapi json bukanlah bahasa pemrograman; itu hanya representasi data. Anda tidak bisa mengatakannya untuk menyatukan string. Tata bahasanya (yang cukup kecil) tidak menyertakan fasilitas apa pun untuk merepresentasikan string pada banyak baris.

Singkatnya merancang semacam pra-prosesor (dan saya, untuk satu, tidak merasa seperti secara efektif membuat bahasa saya sendiri untuk menyelesaikan masalah ini), tidak ada solusi umum untuk masalah ini. JIKA Anda bisa mengubah format data, maka Anda bisa mengganti array string. Kalau tidak, ini adalah salah satu dari banyak cara yang tidak dirancang json untuk keterbacaan manusia.

Mark Adelsberger
sumber
3
Tidak jelas apa yang diinginkan OP, baris baru dalam string, atau mengatur string lebih baik ...
9ilsdx 9rvj 0lo
3
@ 9ilsdx9rvj0lo: Tidak, tidak.
Mark Adelsberger
Mengenai "Pertanyaannya adalah bagaimana membuat kode terlihat lebih bagus dengan memisahkan nilai string di beberapa baris kode ...": untuk solusi pernyataan multi-baris dalam Python, lihat stackoverflow.com/questions/53162/… . Ada perbedaan antara multi-line JSON dan multi-line Python. Multi-line JSON menggunakan '\' diikuti oleh 'n' di JSON, yaitu "\ n" dalam string. Pernyataan Python multi-baris, gunakan '\' diikuti oleh '\ n' yaitu garis miring terbalik pada baris yang akan dilanjutkan. Format Windows: ganti \ n dengan \ r \ n jika sesuai!
Ivan
106

Lihat spesifikasinya ! Produksi char grammar JSON dapat mengambil nilai-nilai berikut:

  • segala-Unicode-karakter-kecuali- "-atau- \-atau-kontrol-karakter
  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u empat-hex-digit

Baris baru adalah "karakter kontrol" jadi, tidak, Anda mungkin tidak memiliki baris baru literal dalam string Anda. Namun Anda dapat menyandikannya menggunakan kombinasi apa pun \ndan yang \rAnda perlukan.

Lightness Races di Orbit
sumber
3
Ini adalah jawaban yang benar karena tidak meninggalkan ambiguitas. Baris baru diperbolehkan, sesuai spesifikasinya, selama mereka lolos dengan benar dengan karakter kontrol.
Ryan
@AliKhaki \ n di JSON tidak akan mencapai hasil yang dicari oleh pertanyaan. Entah Anda memikirkan sesuatu yang lain (yaitu menyematkan karakter baris baru), atau Anda sedang berbicara tentang baris baru dalam string literal (berisi JSON) dalam beberapa bahasa pemrograman, yang lagi-lagi merupakan sesuatu yang berbeda.
Lightness Races dalam Orbit
@LightnessRacesinOrbit ya saya mencari baris baru dalam string
Ali Khaki
46

JSON tidak mengizinkan garis putus-putus untuk dibaca.

Taruhan terbaik Anda adalah menggunakan IDE yang akan digunakan untuk Anda.

James Gentes
sumber
1
Editor seperti BBEdit yang mendukung "soft" line ideal. Ini membungkus teks sehingga semuanya muncul dalam area yang terlihat dari jendela editor, tetapi hanya ujung baris yang Anda ketikkan (misalnya, menekan carriage return) yang bertahan dalam file saat disimpan. Memudahkan mengedit JSON dengan string yang sangat panjang tanpa harus menggunakan trik kode atau peretasan.
cshotton
44

Ini adalah pertanyaan yang sangat lama, tetapi saya menemukan ini pada pencarian dan saya pikir saya tahu sumber masalah Anda.

JSON tidak mengizinkan baris baru "nyata" dalam datanya; hanya bisa lolos dari baris baru. Lihat jawabannya dari @ YOU . Menurut pertanyaan, sepertinya Anda mencoba untuk melarikan diri dari jeda baris dalam Python dua cara: dengan menggunakan karakter kelanjutan garis ( "\") atau dengan menggunakan "\n"sebagai pelarian.

Namun perlu diingat: jika Anda menggunakan string dalam python, karakter khusus yang lolos ( "\t", "\n") diterjemahkan ke dalam karakter kontrol NYATA! The "\n"akan diganti dengan karakter kontrol ASCII mewakili karakter baris baru, yang justru karakter yang ilegal di JSON. (Adapun karakter kelanjutan garis, itu hanya mengeluarkan baris baru.)

Jadi yang perlu Anda lakukan adalah mencegah Python keluar dari karakter. Anda dapat melakukan ini dengan menggunakan string mentah (diletakkan rdi depan string, seperti di r"abc\ndef", atau dengan memasukkan garis miring tambahan di depan baris baru ( "abc\\ndef").

Kedua hal di atas, alih-alih mengganti "\n"dengan karakter kontrol ASCII baris baru yang sebenarnya, akan meninggalkan "\n"sebagai dua karakter literal, yang kemudian dapat ditafsirkan JSON sebagai pelarian baris baru.

HardlyKnowEm
sumber
12

Tulis nilai properti sebagai array string. Seperti contoh yang diberikan di sini https://gun.io/blog/multi-line-strings-in-json/ . Ini akan membantu.

Kita selalu dapat menggunakan array string untuk string multiline seperti berikut.

{
    "singleLine": "Some singleline String",
    "multiline": ["Line one", "line Two", "Line Three"]
} 

Dan kita dapat dengan mudah beralih array untuk menampilkan konten dalam mode multi-line.

Sandip Nirmal
sumber
1
Saya sarankan Anda menambahkan informasi dalam jawaban Anda dari tautan, Karena tautan dapat rusak di masa mendatang.
YoungHobbit
5
Tetapi mereka Anda memiliki array, bukan string. Array bukan string. Titik.
9ilsdx 9rvj 0lo
Baru saja memikirkan hal ini. Bagus!
Phillip Jacobs
12

Gunakan json5 (loader) lihat https://json5.org/ - contoh (oleh json5)

{
  lineBreaks: "Look, Mom! \
No \\n's!",
}
Lacom
sumber
Pertanyaan yang diajukan OP. Setidaknya jika dia bisa menggunakan json5.
nomen
10

Apakah mungkin memiliki string multi-line di JSON?

Iya. Saya baru saja menguji ini sekarang dengan browser web Firefox saya dengan menekan F12, mengklik konsol dan mengetik di bagian bawah layar.

x={text:"hello\nworld"}

Objek x baru saja dibuat dari string format JSON yang berisi string multi-line.

console.log(x.text)
hello
world

x.text ditampilkan yang menunjukkan bahwa itu adalah string multi-line.

Dua tes ini menunjukkan bahwa penerjemah Javascript Firefox senang membuat dan menggunakan JSON dengan string multiline.

Lebih banyak tes dengan JSON.stringifydan JSON.parsemenunjukkan Javascript interpreter dapat mengonversi objek yang berisi string multiline ke JSON dan menguraikannya kembali tanpa masalah sama sekali.

Di masa lalu saya telah menyimpan karya lengkap Shakespeare sebagai properti dalam objek JSON dan kemudian mengirimkannya melalui internet, tanpa gangguan.

Contoh

Berikut adalah dua garis string yang dimasukkan lebih dari tiga baris

x={text:"expert\
s\nex\
change"}

Kami dapat menampilkan objek

console.log(x)

memberi

Object { text: "experts\nexchange" }

atau string

console.log(x.text)

memberi

experts
exchange

Akhir baris dalam hasil string dari menggunakan \ n dan beberapa baris input dicapai hanya menggunakan \ di akhir baris.

Dalam praktiknya Anda mungkin ingin menyinkronkan ujung baris Anda dengan yang ada di string, mis

x={text:"experts\n\
exchange"}

Panjang String Multi-Line

console.log("Hello\nWorld".length)
11 
console.log("Hello World".length)
11

Perhatikan bahwa string dengan baris baru tidak lebih panjang dari string dengan spasi. Meskipun dua karakter diketik pada keyboard ('\' dan 'n'), hanya satu karakter yang disimpan dalam string.

Ivan
sumber
3
Pembaca format string JavaScript bukanlah pembaca format string JSON dan sebaliknya, jadi sementara itu berhasil, konsol JavaScript juga menerima x={"a":NaN}dan x={"a":"a \<literal newline with SHIFT>b"}, yang bukan JSON, tetapi JavaScript
cat
9

Gunakan regex untuk mengganti semua kemunculan \r\ndengan \\n.

Ini bekerja untuk saya dalam scala.

val newstr = str.replace("\r\n", "\\n")
Sikander
sumber
Mengapa 3 backslash?
neXus
6
@neXus Saya tidak tahu mengapa tetapi seseorang telah mengeditnya menjadi 3 backslash. Terima kasih kepada LightnessRacesInOrbit untuk memperbaikinya.
Sikander
5

Jika Anda bersedia menggunakan Node.js, Anda dapat melakukan ini:

module.exports = {

  multilineStr: `

     dis my life 
     it's now or never

  `

}

Anda dapat mengimpor dengan Node.js dan mengonversinya ke JSON dengan mudah seperti:

echo `node -pe 'JSON.stringify(require("./json-mod.js"))'`

dan Anda mendapatkan:

{"multilineStr":"\n \n dis my life\n it's now or never\n \n "}

cara kerjanya : Anda menggunakan Node.js untuk memuat modul JS, yang membuat objek JS yang dapat dengan mudah diubah menjadi JSON oleh Node.js. Opsi -e mengevaluasi string, dan -popsi menggemakan hasil kembalinya operasi Node.js terakhir ke stdout.

Jika Anda ingin memuat skrip .js yang ada di direktori kerja yang berbeda, Anda harus mengganti string "" dan '':

my_script='../json-mod.js'
echo `node -pe "JSON.stringify(require('$my_script'))"`
Alexander Mills
sumber
-4

Coba gunakan base64nilai string yang disandikan. Bekerja untuk saya sebagian besar waktu.

{
    "singleLine": "Some singleline String",
    "multiline": ["Line one", "line Two", "Line Three"]
} 

setelah base64string dikodekan terlihat seperti

{
    "singleLine": "Some singleline String",
    "multiline": "TGluZSBvbmUKTGluZSBUd28KTGluZSBUaHJlZQ=="
} 

encoding dan decoding base64 tersedia dalam semua bahasa.

Sunit Parekh
sumber
7
Anda perlu kode khusus untuk menampilkannya, Anda mengubah string menjadi array. Ini bukan solusi
tom10271
3
Saya pikir ini adalah ide yang buruk - itu mengaburkan konten yang tidak perlu dan memerlukan kode tambahan, waktu, memori dan alat untuk menghasilkan dan mengkonsumsinya. Memindai melalui string dan mengganti karakter khusus tentu saja memerlukan kode tambahan, waktu dan memori juga, tapi pasti kurang dari base64 encoding dan decoding
Semanino
Ini adalah ide yang buruk karena keterbacaan JSON hilang, dan juga seperti @ tom10271 disebutkan, Anda perlu operasi tambahan untuk menggunakan json
T90
-23

letakkan teks multiline pada file txt lalu

var str = {
    text: cat('path_to_file/text.txt')
}

(Ini bekerja pada mongoDB)

flaalf
sumber
11
-1: ini adalah jawaban yang menyesatkan. Ini bukan JSON yang valid juga tidak berfungsi dalam javascript karena tidak ada fungsi bernama cat.
Martin Schuhfuß