Saya memiliki jenis string berikut
var string = "'string, duppi, du', 23, lala"
Saya ingin membagi string menjadi array pada setiap koma, tetapi hanya koma di luar tanda kutip tunggal.
Saya tidak tahu ekspresi reguler yang tepat untuk perpecahan ...
string.split(/,/)
akan memberi saya
["'string", " duppi", " du'", " 23", " lala"]
tetapi hasilnya harus:
["string, duppi, du", "23", "lala"]
Apakah ada solusi lintas-browser?
javascript
regex
split
Hans
sumber
sumber
Jawaban:
Penolakan
Pembaruan 2014-12-01: Jawaban di bawah ini hanya berfungsi untuk satu format CSV yang sangat spesifik. Seperti yang ditunjukkan dengan benar oleh DG di komentar , solusi ini tidak sesuai dengan definisi CSV RFC 4180 dan juga tidak sesuai dengan format Microsoft Excel. Solusi ini hanya mendemonstrasikan bagaimana seseorang dapat mengurai satu baris input CSV (non-standar) yang berisi campuran jenis string, di mana string mungkin berisi tanda kutip dan koma yang lolos.
Solusi CSV non-standar
Seperti yang ditunjukkan austincheney dengan benar , Anda benar-benar perlu mengurai string dari awal hingga akhir jika Anda ingin menangani string yang dikutip dengan benar yang mungkin berisi karakter yang lolos. Selain itu, OP tidak secara jelas mendefinisikan apa itu "string CSV" sebenarnya. Pertama kita harus menentukan apa yang merupakan string CSV yang valid dan nilai individualnya.
Diberikan: Definisi "CSV String"
Untuk tujuan diskusi ini, "string CSV" terdiri dari nol atau lebih nilai, di mana beberapa nilai dipisahkan oleh koma. Setiap nilai dapat terdiri dari:
Aturan / Catatan:
'that\'s cool'
.\'
dalam nilai kutip tunggal.\"
dalam nilai kutip ganda.Temukan:
Fungsi JavaScript yang mengubah string CSV yang valid (seperti yang didefinisikan di atas) menjadi larik nilai string.
Larutan:
Ekspresi reguler yang digunakan oleh solusi ini kompleks. Dan (IMHO) semua ekspresi reguler non-sepele harus disajikan dalam mode spasi bebas dengan banyak komentar dan lekukan. Sayangnya, JavaScript tidak mengizinkan mode spasi bebas. Dengan demikian, ekspresi reguler yang diterapkan oleh solusi ini pertama kali disajikan dalam sintaks ekspresi reguler asli (diekspresikan menggunakan handy Python
r'''...'''
sintaks string mentah-multi-baris ).Pertama di sini adalah ekspresi reguler yang memvalidasi bahwa string CVS memenuhi persyaratan di atas:
Ekspresi reguler untuk memvalidasi "string CSV":
Jika sebuah string cocok dengan ekspresi reguler di atas, string tersebut adalah string CSV yang valid (sesuai dengan aturan yang dinyatakan sebelumnya) dan dapat diurai menggunakan ekspresi reguler berikut. Ekspresi reguler berikut kemudian digunakan untuk mencocokkan satu nilai dari string CSV. Ini diterapkan berulang kali hingga tidak ada lagi kecocokan yang ditemukan (dan semua nilai telah diuraikan).
Ekspresi reguler untuk mengurai satu nilai dari string CSV yang valid:
Perhatikan bahwa ada satu nilai kasus khusus yang tidak cocok dengan ekspresi reguler ini - nilai terakhir bila nilai itu kosong. Kasus khusus "nilai terakhir kosong" ini diuji dan ditangani oleh fungsi JavaScript yang mengikuti.
Fungsi JavaScript untuk mengurai string CSV:
Contoh masukan dan keluaran:
Dalam contoh berikut, kurung kurawal digunakan untuk membatasi
{result strings}
. (Ini untuk membantu memvisualisasikan spasi depan / belakang dan string panjang-nol.)Catatan tambahan:
Solusi ini mengharuskan string CSV menjadi "valid". Misalnya, nilai tanpa tanda kutip tidak boleh berisi garis miring terbalik atau tanda kutip, misalnya string CSV berikut tidak valid:
Ini sebenarnya bukan batasan karena setiap sub-string dapat direpresentasikan sebagai nilai kutip tunggal atau ganda. Perhatikan juga bahwa solusi ini hanya mewakili satu kemungkinan definisi untuk "nilai yang dipisahkan koma".
Edit riwayat
sumber
"field one", "field two", "a ""final"" field containing two double quote marks"
Saya belum menguji jawaban Trevor Dixon di halaman ini, tetapi ini adalah jawaban yang membahas definisi CSV RFC 4180.Solusi RFC 4180
Ini tidak menyelesaikan string dalam pertanyaan karena formatnya tidak sesuai dengan RFC 4180; pengkodean yang dapat diterima keluar dari tanda kutip ganda dengan tanda kutip ganda. Solusi di bawah ini berfungsi dengan benar dengan file CSV d / l dari spreadsheet google.
PEMBARUAN (3/2017)
Mengurai satu baris akan salah. Menurut bidang RFC 4180 mungkin berisi CRLF yang akan menyebabkan pembaca baris apa pun merusak file CSV. Berikut adalah versi terbaru yang mengurai string CSV:
JAWABAN LAMA
(Solusi garis tunggal)
Dan untuk bersenang-senang, berikut adalah cara Anda membuat CSV dari array:
sumber
Tata bahasa PEG (.js) yang menangani contoh RFC 4180 di http://en.wikipedia.org/wiki/Comma-separated_values :
Uji di http://jsfiddle.net/knvzk/10 atau https://pegjs.org/online .
Unduh parser yang dibuat di https://gist.github.com/3362830 .
sumber
Saya memiliki kasus penggunaan yang sangat spesifik di mana saya ingin menyalin sel dari Google Sheets ke aplikasi web saya. Sel dapat menyertakan tanda kutip ganda dan karakter baris baru. Menggunakan salin dan tempel, sel dibatasi oleh karakter tab, dan sel dengan data ganjil dikutip ganda. Saya mencoba solusi utama ini, artikel tertaut menggunakan regexp, dan Jquery-CSV, dan CSVToArray. http://papaparse.com/ Adalah satu-satunya yang berhasil di luar kotak. Salin dan tempel mulus dengan Google Sheets dengan opsi deteksi otomatis default.
sumber
Saya menyukai jawaban FakeRainBrigand, namun berisi beberapa masalah: Jawaban ini tidak dapat menangani spasi kosong antara kutipan dan koma, dan tidak mendukung 2 koma yang berurutan. Saya mencoba mengedit jawabannya tetapi suntingan saya ditolak oleh pengulas yang tampaknya tidak memahami kode saya. Ini adalah versi kode FakeRainBrigand saya. Ada juga biola: http://jsfiddle.net/xTezm/46/
sumber
Orang-orang sepertinya menentang RegEx untuk ini. Mengapa?
Ini kodenya. Saya juga membuat biola .
sumber
Menambahkan satu lagi ke daftar, karena menurut saya semua hal di atas tidak cukup "KISS".
Yang ini menggunakan regex untuk menemukan koma atau baris baru sambil melewati item yang dikutip. Semoga ini adalah sesuatu yang bisa dibaca oleh noobies sendiri. The
splitFinder
regexp memiliki tiga hal itu tidak (split oleh|
):,
- menemukan koma\r?\n
- menemukan jalur baru, (berpotensi dengan carriage return jika eksportir bersikap baik)"(\\"|[^"])*?"
- melewatkan apa pun yang diapit tanda kutip, karena koma dan baris baru tidak penting di sana. Jika ada kutipan yang lolos\\"
dalam item yang dikutip, itu akan ditangkap sebelum kutipan akhir dapat ditemukan.sumber
Id, Name, Age 1, John Smith, 65 2, Jane Doe, 30
bagaimana saya bisa mengurai berdasarkan kolom yang saya tentukan?[{Id: 1, Name: "John Smith", Age: 65}, {Id: 2, Name: "Jane Doe", Age: 30}]
Jika Anda dapat membuat pembatas kutipan menjadi tanda kutip ganda, maka ini adalah duplikat kode Contoh JavaScript untuk mengurai data CSV .
Anda dapat menerjemahkan semua tanda kutip tunggal menjadi tanda kutip ganda terlebih dahulu:
... atau Anda dapat mengedit ekspresi reguler dalam pertanyaan itu untuk mengenali tanda kutip tunggal, bukan tanda kutip ganda:
Namun, ini mengasumsikan markup tertentu yang tidak jelas dari pertanyaan Anda. Harap klarifikasi tentang berbagai kemungkinan markup, sesuai komentar saya atas pertanyaan Anda.
sumber
Jawaban saya menganggap masukan Anda adalah cerminan kode / konten dari sumber web di mana karakter tanda kutip tunggal dan ganda sepenuhnya dapat dipertukarkan asalkan terjadi sebagai kumpulan pencocokan yang tidak lolos.
Anda tidak dapat menggunakan ekspresi reguler untuk ini. Anda sebenarnya harus menulis parser mikro untuk menganalisis string yang ingin Anda pisahkan. Demi jawaban ini, saya akan menyebut bagian yang dikutip dari string Anda sebagai sub-string. Anda harus berjalan melintasi tali secara khusus. Pertimbangkan kasus berikut:
Dalam hal ini Anda sama sekali tidak tahu di mana sub-string dimulai atau diakhiri hanya dengan menganalisis input untuk pola karakter. Sebaliknya, Anda harus menulis logika untuk membuat keputusan tentang apakah karakter kutipan digunakan karakter kutipan, tidak dikutip, dan karakter kutipan tidak mengikuti pelarian.
Saya tidak akan menulis tingkat kerumitan kode itu untuk Anda, tetapi Anda dapat melihat sesuatu yang baru-baru ini saya tulis yang memiliki pola yang Anda butuhkan. Kode ini tidak ada hubungannya dengan koma, tetapi merupakan micro-parser yang cukup valid untuk Anda ikuti saat menulis kode Anda sendiri. Perhatikan fungsi asifix dari aplikasi berikut:
https://github.com/austincheney/Pretty-Diff/blob/master/fulljsmin.js
sumber
Untuk melengkapi jawaban ini
Jika Anda perlu mengurai kutipan yang lolos dengan kutipan lain, contoh:
Kamu bisa memakai
sumber
"jjj "" kkk""","123"
Saat membaca file CSV menjadi string, file ini berisi nilai null di antara string, jadi cobalah dengan \ 0 baris demi baris. Ini bekerja untuk saya.
sumber
Saya juga menghadapi masalah yang sama ketika saya harus mengurai file CSV.
File tersebut berisi alamat kolom yang berisi ','.
Setelah mem-parsing file CSV itu ke JSON, saya mendapatkan pemetaan kunci yang tidak cocok saat mengonversinya menjadi file JSON.
Saya menggunakan Node.js untuk mem -parsing file dan perpustakaan seperti baby parse dan csvtojson .
Contoh file -
Saat saya mem-parsing secara langsung tanpa menggunakan baby parse di JSON, saya mendapatkan:
Jadi saya menulis kode yang menghapus koma (,) dengan pembatas lain dengan setiap bidang:
Fungsi yang dikembalikan bisa diteruskan ke pustaka csvtojson dan dengan demikian hasilnya bisa digunakan.
Sekarang Anda bisa mendapatkan output seperti:
sumber
Tidak ada regexp, dapat dibaca, dan sesuai dengan https://en.wikipedia.org/wiki/Comma-separated_values#Basic_rules :
sumber
Menurut posting blog ini , fungsi ini harus melakukannya:
Anda akan menyebutnya seperti ini:
Jenis jsfiddle ini berfungsi, tetapi sepertinya beberapa elemen memiliki spasi di depannya.
sumber
"'string, duppi, du', 23, lala"
["'string"," duppi"," du'"," 23"," lala"]
"'"
ke'"'
dan sebaliknya.'"string, duppi, du", 23, lala'
menghasilkan:['"string',' duppi'.' du"',' 23',' lala']
Ekspresi reguler untuk menyelamatkan! Beberapa baris kode ini menangani bidang yang dikutip dengan benar dengan koma, tanda kutip, dan baris baru yang disematkan berdasarkan standar RFC 4180.
Kecuali dinyatakan di tempat lain, Anda tidak memerlukan mesin negara hingga. Ekspresi reguler menangani RFC 4180 dengan baik berkat tampilan positif di belakang, tampilan negatif, dan tampilan positif.
Clone / unduh kode di https://github.com/peterthoeny/parse-csv-js
sumber
Selain dari jawaban yang sangat bagus dan lengkap dari ridgerunner , saya memikirkan solusi yang sangat sederhana ketika backend Anda menjalankan PHP.
Menambahkan file PHP ini untuk domain Anda backend (katakanlah:
csv.php
)Sekarang tambahkan fungsi ini ke toolkit JavaScript Anda (saya harus direvisi sedikit untuk membuat crossbrowser saya percaya).
Anda akan dikenakan biaya satu panggilan Ajax, tetapi setidaknya Anda tidak akan menduplikasi kode atau menyertakan pustaka eksternal apa pun.
Ref: http://php.net/manual/en/function.str-getcsv.php
sumber
Anda bisa menggunakan papaparse.js seperti contoh di bawah ini:
Jangan lupa untuk memasukkan papaparse.js di folder yang sama.
sumber