Saya mencari saran tentang cara menangani file csv yang sedang dibuat, kemudian diunggah oleh pelanggan kami, dan yang mungkin memiliki koma dalam suatu nilai, seperti nama perusahaan.
Beberapa ide yang kami lihat adalah: Pengidentifikasi yang dikutip (nilai "," nilai "," dll) atau menggunakan | bukannya koma. Masalah terbesar adalah kita harus membuatnya mudah, atau pelanggan tidak akan melakukannya.
Jawaban:
Seperti yang dikatakan orang lain, Anda harus keluar dari nilai yang menyertakan kutipan. Berikut adalah pembaca CSV kecil di C♯ yang mendukung nilai-nilai yang dikutip, termasuk kutipan yang disematkan dan pengembalian carriage.
Omong-omong, ini adalah kode yang diuji unit. Saya mempostingnya sekarang karena pertanyaan ini tampaknya banyak muncul dan orang lain mungkin tidak ingin seluruh perpustakaan ketika dukungan CSV sederhana akan dilakukan.
Anda dapat menggunakannya sebagai berikut:
Ini kelasnya. Perhatikan bahwa Anda dapat menggunakan
Csv.Escape
fungsi ini untuk menulis CSV yang valid juga.sumber
Untuk 2017, csv sepenuhnya ditentukan - RFC 4180.
Ini adalah spesifikasi yang sangat umum, dan sepenuhnya dicakup oleh banyak perpustakaan ( contoh ).
Cukup gunakan perpustakaan csv yang mudah tersedia - artinya RFC 4180.
Sebenarnya ada spesifikasi untuk format CSV dan cara menangani koma:
http://tools.ietf.org/html/rfc4180
Jadi, untuk memiliki nilai
foo
danbar,baz
, Anda melakukan ini:Persyaratan penting lainnya untuk dipertimbangkan (juga dari spesifikasi):
sumber
System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator
.Format CSV menggunakan koma untuk memisahkan nilai, nilai yang berisi carriage return, linefeed, koma, atau tanda kutip ganda dikelilingi oleh tanda kutip ganda. Nilai yang berisi kutipan ganda dikutip dan setiap kutipan literal diloloskan oleh kutipan sebelumnya: Sebagai contoh, 3 nilai:
akan dikodekan sebagai:
Setiap bidang dapat dikutip tetapi hanya bidang yang mengandung koma, CR / NL, atau kutipan harus dikutip.
Tidak ada standar nyata untuk format CSV, tetapi hampir semua aplikasi mengikuti konvensi yang didokumentasikan di sini . RFC yang disebutkan di tempat lain bukanlah standar untuk CSV, itu adalah RFC untuk menggunakan CSV dalam MIME dan mengandung beberapa batasan tidak konvensional dan tidak perlu yang menjadikannya tidak berguna di luar MIME.
Sebuah Gotcha yang banyak modul CSV saya lihat tidak mengakomodasi adalah kenyataan bahwa beberapa baris dapat dikodekan dalam satu bidang yang berarti Anda tidak dapat mengasumsikan bahwa setiap baris adalah catatan yang terpisah, Anda juga perlu tidak mengizinkan baris baru di Anda data atau bersiaplah untuk menangani ini.
sumber
Letakkan tanda kutip ganda di sekitar string. Itulah yang dilakukan Excel pada umumnya .
Ala Eli,
sumber
Anda dapat menempatkan tanda kutip ganda di sekitar bidang. Saya tidak suka pendekatan ini, karena menambahkan karakter khusus lain (kutipan ganda). Cukup tentukan karakter pelarian (biasanya backslash) dan gunakan di mana pun Anda perlu melarikan diri sesuatu:
Anda tidak harus mencoba mencocokkan kutipan, dan Anda memiliki lebih sedikit pengecualian untuk diuraikan. Ini menyederhanakan kode Anda juga.
sumber
Ada perpustakaan yang tersedia melalui nuget untuk menangani hampir semua CSV (.net) yang terbentuk dengan baik - CsvHelper
Contoh untuk memetakan ke kelas:
Contoh untuk membaca masing-masing bidang:
Membiarkan klien mengarahkan format file:
,
adalah pembatas bidang standar,"
adalah nilai standar yang digunakan untuk keluar dari bidang yang berisi pembatas, kutipan, atau akhir baris.Untuk menggunakan (misalnya)
#
untuk bidang dan'
untuk melarikan diri:Lebih Banyak Dokumentasi
sumber
CsvHelper
perpustakaan untuk menyelesaikan masalah OP.Seperti yang disebutkan dalam komentar saya untuk jawaban harpo, solusinya bagus dan berfungsi dalam banyak kasus, namun dalam beberapa skenario ketika koma berbatasan langsung satu sama lain, gagal terpecah pada koma.
Ini karena string Regex berperilaku tidak terduga sebagai string vertabim. Agar perilaku ini benar, semua "karakter dalam string regex harus diloloskan secara manual tanpa menggunakan pelarian vertabim.
Yaitu. Regex harus menggunakan escapes manual ini:
",(?=(?:[^\"\"]*\"\"[^\"\"]*\"\")*(?![^\"\"]*\"\"))"
yang diterjemahkan menjadi
",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"
Saat menggunakan string vertabim
@",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"
berperilaku sebagai berikut seperti yang Anda lihat jika Anda men-debug regex:Jadi secara ringkas, saya merekomendasikan solusi harpo, tapi hati-hati dengan gotcha kecil ini!
Saya telah memasukkan ke dalam CsvReader sedikit failafe opsional untuk memberi tahu Anda jika kesalahan ini terjadi (jika Anda memiliki jumlah kolom yang sudah diketahui sebelumnya):
Ini dapat disuntikkan melalui konstruktor:
sumber
[^""]
sama dengan[^"]
? Duplikasi karakter di dalam spesifikasi kelas karakter adalah mubazir, bukan?Tambahkan referensi ke Microsoft.VisualBasic (ya, katanya VisualBasic tetapi bekerja di C # juga - ingat bahwa pada akhirnya itu semua hanya IL).
Gunakan
Microsoft.VisualBasic.FileIO.TextFieldParser
kelas untuk mem-parsing file CSV Berikut adalah contoh kode:sumber
parser.HasFieldsEnclosedInQuotes = true;
dan file input harus menyertakan bidang yang berisi koma dalam tanda kutip sesuai dengan spesifikasi CSV - excel sudah melakukannya.Anda dapat menggunakan "pembatas" alternatif seperti ";" atau "|" tetapi paling sederhana mungkin hanya mengutip yang didukung oleh sebagian besar perpustakaan CSV (layak) dan spreadsheet yang paling layak.
Untuk lebih lanjut tentang pembatas CSV dan spesifikasi untuk format standar untuk menggambarkan pembatas dan mengutip, lihat halaman web ini
sumber
Jika Anda menggunakan sistem * nix , memiliki akses ke
sed
dan hanya ada satu atau lebih koma yang tidak diinginkan di bidang spesifik CSV Anda, Anda dapat menggunakan satu-liner berikut untuk melampirkannya"
sebagai Bagian RFC4180 2 mengusulkan:Tergantung pada bidang mana koma yang tidak diinginkan mungkin ada di Anda harus mengubah / memperpanjang kelompok penangkap regex (dan substitusi).
Contoh di atas akan menyertakan bidang keempat (dari enam) dalam tanda kutip.
Dalam kombinasi dengan
--in-place
opsi- Anda dapat menerapkan perubahan ini langsung ke file.Untuk "membangun" regex yang tepat, ada prinsip sederhana untuk diikuti:
[^,]*,
dan menempatkan semuanya bersama-sama dalam kelompok penangkapan.(.*)
.,.*
dan menempatkan semuanya dalam satu grup penangkap.Berikut ini adalah ikhtisar singkat dari berbagai regex / substitusi yang mungkin tergantung pada bidang tertentu. Jika tidak diberikan, substitusi adalah
\1"\2"\3
.Jika Anda ingin menghapus koma yang tidak diinginkan dengan menambahkan
sed
tanda kutip, lihat jawaban ini .sumber
Jika Anda merasa ingin menciptakan kembali roda, yang berikut ini mungkin cocok untuk Anda:
sumber
Di Eropa kami memiliki masalah ini harus lebih awal dari pertanyaan ini. Di Eropa kami menggunakan semua koma untuk titik desimal. Lihat angka-angka di bawah ini:
Jadi tidak mungkin menggunakan pemisah koma untuk file CSV. Karena alasan itu, file CSV di Eropa dipisahkan oleh tanda titik koma (
;
) .Program seperti Microsoft Excel dapat membaca file dengan titik koma dan dimungkinkan untuk beralih dari pemisah. Anda bahkan dapat menggunakan tab (
\t
) sebagai pemisah. Lihat jawaban ini dari Pengguna Perjamuan .sumber
Jika Anda tertarik pada latihan yang lebih mendidik tentang cara mem-parsing file secara umum (menggunakan CSV sebagai contoh), Anda dapat memeriksa artikel ini oleh Julian Bucknall. Saya suka artikel itu karena memecah hal-hal menjadi masalah yang jauh lebih kecil yang jauh lebih sulit diatasi. Pertama-tama Anda membuat tata bahasa, dan setelah Anda memiliki tata bahasa yang baik, itu adalah proses yang relatif mudah dan metodis untuk mengubah tata bahasa menjadi kode.
Artikel menggunakan C # dan memiliki tautan di bagian bawah untuk mengunduh kode.
sumber
Ini solusi kecil yang rapi:
Anda dapat menggunakan Tanda Angka Bawah Yunani sebagai gantinya (U + 0375)
Sepertinya ini ͵
Menggunakan metode ini menghemat banyak sumber daya juga ...
sumber
Cukup gunakan SoftCircuits.CsvParser di NuGet. Ini akan menangani semua detail untuk Anda dan secara efisien menangani file yang sangat besar. Dan, jika diperlukan, bahkan dapat mengimpor / mengekspor objek dengan memetakan kolom ke properti objek. Selain itu, pengujian saya menunjukkan rata-rata hampir 4 kali lebih cepat daripada CsvHelper yang populer.
sumber
Karena ini adalah praktik umum, mari kita mulai dari aturan praktis:
Jangan gunakan CSV, gunakan XML dengan perpustakaan untuk membaca & menulis file xml.
Jika Anda harus menggunakan CSV. Lakukan dengan benar dan gunakan perpustakaan gratis untuk mem-parsing dan menyimpan file CSV.
Untuk membenarkan 1), sebagian besar parser CSV tidak menyandikan sadar sehingga jika Anda tidak berurusan dengan US-ASCII, Anda meminta masalah. Misalnya excel 2002 menyimpan CSV dalam pengkodean lokal tanpa catatan tentang pengkodean. Standar CSV tidak diadopsi secara luas :(. Di sisi lain standar xml diadopsi dengan baik dan menangani pengodean dengan cukup baik.
Untuk membenarkan 2), Ada banyak parser csv sekitar untuk hampir semua bahasa sehingga tidak perlu menemukan kembali roda bahkan jika solusi terlihat cukup sederhana.
Untuk beberapa nama:
untuk penggunaan python build in csv module
untuk perl periksa CPAN dan Teks :: CSV
untuk php gunakan fungsi build in fgetcsv / fputcsv
untuk java periksa pustaka SuperCVS
Benar-benar tidak perlu menerapkan ini dengan tangan jika Anda tidak akan menguraikannya di perangkat tertanam.
sumber
Anda dapat membaca file csv seperti ini.
ini memanfaatkan pemisahan dan merawat ruang.
sumber
Pertama, mari kita bertanya pada diri sendiri, "Mengapa kita merasa perlu untuk menangani koma secara berbeda untuk file CSV?"
Bagi saya, jawabannya adalah, "Karena ketika saya mengekspor data ke file CSV, koma di bidang hilang dan bidang saya dipisahkan menjadi beberapa bidang di mana koma muncul di data asli." (Itu karena koma adalah karakter pemisah bidang CSV.)
Bergantung pada situasi Anda, semi-titik dua juga dapat digunakan sebagai pemisah bidang CSV.
Dengan persyaratan saya, saya dapat menggunakan karakter, misalnya, tanda kutip tunggal rendah-9, yang terlihat seperti koma.
Jadi, inilah cara Anda dapat melakukannya di Go:
Karakter tanda koma kedua dalam fungsi Ganti adalah desimal 8218.
Ketahuilah bahwa jika Anda memiliki klien yang mungkin hanya memiliki pembaca teks ascii saja maka karakter decima 8218 ini tidak akan terlihat seperti koma. Jika ini adalah kasus Anda, maka saya akan merekomendasikan mengelilingi lapangan dengan koma (atau titik koma) dengan tanda kutip ganda per RFC 4128: https://tools.ietf.org/html/rfc4180
sumber
Saya biasanya URL-encode bidang yang dapat memiliki koma atau karakter khusus apa pun. Dan kemudian decode ketika sedang digunakan / ditampilkan dalam media visual apa pun.
(koma menjadi% 2C)
Setiap bahasa harus memiliki metode penyandian URL dan dekode string.
misalnya di java
Saya tahu ini adalah solusi yang sangat umum dan mungkin tidak ideal untuk situasi di mana pengguna ingin melihat konten file csv, secara manual.
sumber
Saya biasanya melakukan ini dalam rutinitas parsing file CSV saya. Asumsikan bahwa variabel 'baris' adalah satu baris dalam file CSV dan semua nilai kolom diapit dengan tanda kutip ganda. Setelah dua baris di bawah ini dieksekusi, Anda akan mendapatkan kolom CSV di koleksi 'nilai'.
sumber
Solusi paling sederhana yang saya temukan adalah yang digunakan LibreOffice:
"
dengan”
Anda juga bisa menggunakan yang digunakan Excel:
"
dengan""
Perhatikan orang lain yang direkomendasikan untuk melakukan hanya langkah 2 di atas, tetapi itu tidak bekerja dengan garis-garis di mana a
"
diikuti oleh,
, seperti dalam CSV di mana Anda ingin memiliki satu kolom dengan stringhello",world
, seperti yang dibaca CSV:Yang diartikan sebagai baris dengan dua kolom:
hello
danworld"
sumber
hello",world
Bidang Anda hanya perlu disimpan sebagai"hello"",world"
, yang dapat diurai 100% dengan benar.sumber
Saya menggunakan perpustakaan Csvreader tetapi dengan menggunakan itu saya mendapatkan data dengan meledak dari koma (,) dalam nilai kolom.
Jadi Jika Anda ingin menyisipkan data file CSV yang berisi koma (,) di sebagian besar nilai kolom, Anda dapat menggunakan fungsi di bawah ini. Tautan penulis => https://gist.github.com/jaywilliams/385876
sumber
Saya menggunakan papaParse perpustakaan untuk memiliki file CSV diuraikan dan memiliki pasangan nilai kunci (kunci / header / baris pertama nilai file CSV).
berikut ini contoh yang saya gunakan:
https://codesandbox.io/embed/llqmrp96pm
ada file dummy.csv di sana untuk mendapatkan demo penguraian CSV.
Saya sudah menggunakannya dalam reactJS meskipun mudah dan sederhana untuk mereplikasi dalam aplikasi yang ditulis dengan bahasa apa pun.
sumber
Contoh mungkin membantu menunjukkan bagaimana koma dapat ditampilkan dalam file .csv. Buat file teks sederhana sebagai berikut:
Simpan file teks ini sebagai file teks dengan akhiran ".csv" dan buka dengan Excel 2000 dari Windows 10.
aa, bb, cc, d; d "Dalam presentasi spreadsheet, baris di bawah ini akan terlihat seperti baris di atas kecuali di bawah ini menunjukkan koma yang ditampilkan alih-alih tanda titik koma di antara d's." aa, bb, cc, "d, d", Ini berfungsi bahkan di Excel
aa, bb, cc, "d, d", Ini berfungsi bahkan di Excel 2000 aa, bb, cc, "d, d", Ini berfungsi bahkan di Excel 2000 aa, bb, cc, "d, d", Ini berfungsi bahkan di Excel 2000
aa, bb, cc, "d, d", ini gagal di Excel 2000 karena ruang kosong kutipan pertama aa, bb, cc, "d, d", ini gagal di Excel 2000 karena ruang belore kutipan pertama aa, bb, cc, "d, d", ini gagal di Excel 2000 karena ruang memunculkan kutipan pertama
aa, bb, cc, "d, d", Ini berfungsi bahkan di Excel 2000 bahkan dengan spasi sebelum dan sesudah kutipan ke-2. aa, bb, cc, "d, d", Ini berfungsi bahkan di Excel 2000 bahkan dengan spasi sebelum dan sesudah kutipan ke-2. aa, bb, cc, "d, d", Ini berfungsi bahkan di Excel 2000 bahkan dengan spasi sebelum dan sesudah kutipan ke-2.
Aturan: Jika Anda ingin menampilkan koma di sel (bidang) file .csv: "Mulai dan akhiri bidang dengan tanda kutip ganda, tetapi hindari ruang kosong sebelum kutipan pertama"
sumber
Saya pikir solusi termudah untuk masalah ini adalah memiliki pelanggan untuk membuka csv di excel, dan kemudian ctrl + r untuk mengganti semua koma dengan pengidentifikasi apa pun yang Anda inginkan. Ini sangat mudah bagi pelanggan dan hanya membutuhkan satu perubahan dalam kode Anda untuk membaca pembatas pilihan Anda.
sumber
Gunakan karakter tab (\ t) untuk memisahkan bidang.
sumber