Cara terbaik untuk menangani file yang dibatasi

16

Jadi biasanya file CSV menggunakan koma dan karakter kembali sebagai pemisah bidang dan garis.

Ini mengalami masalah yang jelas dengan teks yang dapat berisi kedua karakter ini.

Jelas ada opsi di sana (melarikan diri) tetapi bagaimana orang menangani ini? Gunakan karakter yang berbeda - pipa atau tilda? Lari mereka? Tidak menggunakan file yang dibatasi, itu 2010 dan kami memiliki XML sekarang?

Mencari setidaknya usaha untuk peluang yang layak untuk tidak melihat masalah.

(Untuk lebih jelasnya, ini adalah pertanyaan karena rasa ingin tahu daripada sesuatu yang lebih solid - itu adalah sesuatu yang saya hadapi berulang kali dengan data, selalu mengelilinginya tetapi biasanya terasa sedikit, yah, kotor, dan bertanya-tanya apa pengalaman orang lain).

Jon Hopkins
sumber
Pikirkan baik-baik tentang penggunaan CSV - ini bagus dan mudah untuk ditangani (lihat jawaban untuk aturan pelolosan umum), tetapi itu tidak hampir sama dengan yang seharusnya - jika Anda hanya berkomunikasi dengan program Anda sendiri itu baik-baik saja, tetapi jika Anda ingin mengimpor di tempat lain itu menjadi sedikit aneh karena program yang berbeda mematuhi aturan pelarian yang berbeda.
Michael Kohne
@Michael - Tentu saja. Masalahnya adalah bahwa itu sangat hadir sehingga Anda akan hampir selalu menemukan saat-saat ketika itu adalah pilihan yang sangat menggoda, dan dalam kasus banyak sistem yang lebih tua itu satu-satunya pilihan.
Jon Hopkins
Perpustakaan dewasa ada dalam banyak bahasa (tentu yang umum) untuk membaca dan menulis file yang dibatasi karakter. Mereka akan menangani sebagian besar situasi apa pun. Menulis parser CSV sendiri tampaknya merupakan semacam anti-pola umum.
quentin-starin

Jawaban:

13

Menurut Wikipedia :

Bidang dengan koma yang disematkan harus diapit dengan karakter kutipan ganda.

Dan selanjutnya:

Kolom dengan karakter penawaran ganda harus disertakan dalam karakter penawaran ganda, dan setiap karakter penawaran ganda harus diwakili oleh sepasang karakter penawaran ganda.

Saya tidak tahu siapa yang menemukan itu, tetapi secara efektif menunjukkan bahwa pada akhirnya Anda harus melarikan diri. Itu satu-satunya solusi yang solid. Segala sesuatu yang lain hanyalah lakban di atas lakban: mungkin berfungsi untuk saat ini, tetapi pada akhirnya Anda akan menemukan kasus di mana Anda memerlukan pengecualian untuk pengecualian, dan tidak butuh waktu lama sebelum bola-bola kendali Anda dari aturan adalah cara yang lebih kompleks daripada solusi karakter pelarian yang sederhana.

Tampaknya pencipta CSV pertama kali mencoba menghindari melarikan diri dari koma dengan membuat sintaks khusus yang dikutip ganda, yang memungkinkan penyelamatan koma, tetapi kemudian seseorang ingin menyimpan karakter tanda kutip ganda juga, jadi mereka harus melarikan diri pada saat itu - dengan senang menggunakan double-quote sebagai karakter pelarian. Seandainya mereka memutuskan untuk melarikan diri dengan benar sejak awal, sintaksinya akan lebih mudah sekarang.

Joonas Pulakka
sumber
3
Apa yang seharusnya, dan apa yang .. sering berbeda :)
Tim Post
Saya pikir solusinya cukup ok. Untuk data sederhana, CSV berfungsi dengan baik, untuk data yang kompleks, maka mengutip adalah hal yang perlu, dan melarikan diri "dengan" "melacak kembali ke BASIC.
Ernelli
1
@ Ernelli: Sekarang saya lebih memikirkannya, itu mungkin sebenarnya merupakan kompromi yang masuk akal antara keterbacaan dan kesederhanaan manusia. Masalahnya adalah bahwa itu terlihat jelek bagi manusia , meskipun itu sepele bagi komputer untuk diurai. Dengan demikian, pemesanan lolos hanya untuk kasus yang jarang terjadi ("bidang dengan karakter kutip ganda yang disematkan") menghasilkan output yang biasanya terlihat cukup dapat dibaca manusia. Ini adalah solusi yang baik, dengan asumsi bahwa koma dalam nama bidang lebih sering digunakan daripada tanda kutip ganda dalam nama bidang.
Joonas Pulakka
2

Saya berasumsi Anda memiliki sesuatu seperti ini:

Foo,Baz,,,"Foo,Baz"

Jika string yang berisi pembatas tidak dikutip atau melarikan diri, Anda tidak nyata cara yang dapat diandalkan parsing file.

Namun, Anda dapat memeriksa data untuk menguraikan dan menarik kesimpulan seperti:

  • Pelampung yang dipisahkan koma harus diperlakukan sebagai string
  • Jika baris sebelum atau sesudah ini mengandung pembatas yang lebih sedikit, lewati penguraian baris ini dan catat
  • Perlakukan 'seperti "

Anda memang harus menulis parser untuk menangani hal-hal seperti itu, tetapi itu tidak harus rumit.

Dalam pengalaman saya, mengimpor dump besar dari sesuatu seperti Excel selalu mengakibatkan harus kembali dan meninjau beberapa bola aneh. Tantangan Anda adalah untuk memberikan program anda hanya akal sehat cukup mengenai data sehingga tidak melakukan insert gila. Kemudian tinjau apa yang telah dicatat dan cuci / bilas / ulangi.

Saya pernah menangani FAQ internal untuk perusahaan kecil yang menggunakan semua workstation Ubuntu. Sebagian dari FAQ memberi 'pintasan shell', dan itu muncul di benak saya. Yah, jawabannya juga biasanya dibatasi pipa (yaitu grep foo | sesuatu) dan tidak dikutip atau lolos. Saya merasakan sakit itu :)

Pos Tim
sumber
2

Tidak ada yang salah dengan CSV hingga titik tertentu

CSV bekerja dengan baik untuk data yang didefinisikan secara kaku yang tidak mungkin berubah format dan tidak menimbulkan banyak kejutan pada parser penerima.

Berikut daftar praktis dari gotcha besar:

  1. Melarikan diri "" di dalam "" (bidang berisi pembatas bidang)
  2. "" mengandung CRLF (bidang berisi pembatas baris)
  3. Unicode (format teks yang mendasarinya mungkin tidak cukup)
  4. Terminator saluran yang berbeda untuk OS yang berbeda (apakah CR atau CRLF atau LF atau NUL?)
  5. Komentar sebaris (baris diawali dengan #, //, -,; dll)
  6. Manajemen versi (versi terbaru file berisi lebih atau kurang bidang)
  7. Membedakan antara NULL dan data kosong (, "", kosong tapi ,, apakah nol?)

Anda bisa mendekati ini dengan header meta-data yang menjelaskan bagaimana bidang harus diurai, tetapi Anda juga bisa menggunakan XML. Ini karena jenis kekacauan CSV bentuk bebas yang diciptakan. Pendekatan XML sepertinya terlalu berat untuk apa yang bisa, pada kenyataannya, menjadi masalah sederhana.

Alternatif yang populer adalah strategi "pembatas karakter aneh". Ini mengatasi banyak masalah pelolosan di atas karena Anda menggunakan sesuatu seperti | (pipa) karakter untuk pembatas lapangan, dan CRLF untuk penghentian rekaman. Ini tidak mengatasi masalah bidang multi-garis (kecuali jika Anda menggunakan penghitung bidang) tetapi Anda mendapatkan garis yang diformat dengan baik untuk manusia.

Secara keseluruhan, jika Anda hanya mencari cara sederhana untuk menangani file semacam ini maka, di dunia Java, Anda bisa melempar OpenCSV padanya. Dengan begitu Anda memisahkan semua masalah ke dalam kerangka kerja yang sudah ada.

Gary Rowe
sumber
2

CSV masih merupakan format yang valid dalam banyak situasi, terutama karena masih harus menjadi cara termudah bagi pelanggan untuk menulis data yang perlu diimpor ke dalam aplikasi Anda. Beberapa pelanggan kami suka berurusan dengan XML, mungkin karena itu sangat bertele-tele dan memiliki semua kurung sudut "menakutkan". Jauh lebih mudah bagi mereka untuk membungkus otak mereka di sekitar daftar item sederhana yang dipisahkan oleh karakter yang disepakati, dan juga setuju bahwa karakter yang sama tidak akan diizinkan dalam isi bidang.

Yang mengatakan, Anda masih harus menangani input dengan benar dan memeriksa situasi di mana mereka menggunakan karakter yang tidak valid. Saya sudah mulai menggunakan FileHelpers untuk kebutuhan parsing CSV saya.

Dave
sumber
1

Saya biasanya tetap berpegang pada standar dan melarikan diri dari mereka. dalam kebanyakan bahasa pemrograman ada dukungan builtin yang baik atau perpustakaan yang baik tersedia.

itu tergantung pada situasi format mana yang akan digunakan dan CSV adalah format yang masuk akal untuk bertukar struktur format data sederhana.

Salandur
sumber
0

Lupakan CSV, gunakan JSON . Mudah ditulis, mudah diurai. XML sangat 2005 .

pengguna281377
sumber
6
dan memiliki masalah yang sama ketika Anda ingin menggunakan karakter yang merupakan bagian dari format JSON (seperti {atau,)
Salandur
Salandur: Tidak sama sekali! Ada aturan pasti bagaimana cara melarikan diri! Tapi {dan, bahkan tidak perlu melarikan diri, karena di dalam adalah string, mereka tidak ambigu!
user281377
1
Baik dan bagus, tapi saya tidak ingat excel memiliki fitur "Ekspor ke JSON" :) Ada kalanya Anda harus menguraikan hal-hal aneh, jika hanya untuk membuatnya menjadi format yang lebih menyenangkan.
Tim Post
1
Dan JSON sangat brilian untuk mengedarkan sekitar satu juta objek dengan bentuk yang sama. Oh tunggu.
Frank Shearar
1
JSON tidak menawarkan peningkatan dibandingkan CSV sehubungan dengan pertanyaan ini dan yang terpenting adalah kurangnya interoperabilitas dengan banyak aplikasi (seperti yang telah disebutkan, tidak dapat mengimpor atau mengekspor dari Office, SQL DBs dll). JSON sangat bagus untuk operasi sisi klien yang ringan dan internal, tetapi XML jauh lebih baik untuk melewatkan data antar aplikasi.
Dan Diplo
0

Biasanya, apa yang saya lakukan adalah mendapatkan TSV (tab-separated values) daripada file CSV, tarik file tersebut ke Emacs dan lihat karakter mana yang jarang digunakan oleh PERNAH ($ biasanya merupakan pilihan yang baik di sekitar sini), dan kemudian saya mengonversi semua tab menjadi $.

Dari sana, GNU AWK dapat dikatakan menggunakan $ sebagai pemisah bidang, dan Bob adalah paman Anda.

John R. Strohm
sumber