Berurusan dengan koma dalam file CSV

472

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.

Bob The Janitor
sumber
pelanggan menulis dan mengunggahnya
Bob The Janitor
1
Berikut ini adalah solusi untuk mengelola commos di dalam file csv. kunjungi stackoverflow.com/questions/9889225/…
Hasan Abrar
di iOS, pada dasarnya Anda harus menggunakan github.com/Flinesoft/CSVImporter
Fattie
3
Perhatikan bahwa QA ini sudah tua. Saat ini csv berarti RFC 4180 dan hanya itu.
Fattie
Saya memiliki masalah yang sama persis, mencoba total kolom dalam file csv yang dipisahkan koma. Tidak ada masalah dengan perintah awk. Sayangnya beberapa sel mungkin mengandung koma (dalam alamat misalnya), sel lain tidak akan. Mencari solusi yang kompatibel dengan Linux tetapi tidak yakin harus mulai dari mana.
greenage

Jawaban:

223

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:

using System;
public class test
{
    public static void Main()
    {
        using ( CsvReader reader = new CsvReader( "data.csv" ) )
        {
            foreach( string[] values in reader.RowEnumerator )
            {
                Console.WriteLine( "Row {0} has {1} values.", reader.RowIndex, values.Length );
            }
        }
        Console.ReadLine();
    }
}

Ini kelasnya. Perhatikan bahwa Anda dapat menggunakan Csv.Escapefungsi ini untuk menulis CSV yang valid juga.

using System.IO;
using System.Text.RegularExpressions;

public sealed class CsvReader : System.IDisposable
{
    public CsvReader( string fileName ) : this( new FileStream( fileName, FileMode.Open, FileAccess.Read ) )
    {
    }

    public CsvReader( Stream stream )
    {
        __reader = new StreamReader( stream );
    }

    public System.Collections.IEnumerable RowEnumerator
    {
        get {
            if ( null == __reader )
                throw new System.ApplicationException( "I can't start reading without CSV input." );

            __rowno = 0;
            string sLine;
            string sNextLine;

            while ( null != ( sLine = __reader.ReadLine() ) )
            {
                while ( rexRunOnLine.IsMatch( sLine ) && null != ( sNextLine = __reader.ReadLine() ) )
                    sLine += "\n" + sNextLine;

                __rowno++;
                string[] values = rexCsvSplitter.Split( sLine );

                for ( int i = 0; i < values.Length; i++ )
                    values[i] = Csv.Unescape( values[i] );

                yield return values;
            }

            __reader.Close();
        }
    }

    public long RowIndex { get { return __rowno; } }

    public void Dispose()
    {
        if ( null != __reader ) __reader.Dispose();
    }

    //============================================


    private long __rowno = 0;
    private TextReader __reader;
    private static Regex rexCsvSplitter = new Regex( @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))" );
    private static Regex rexRunOnLine = new Regex( @"^[^""]*(?:""[^""]*""[^""]*)*""[^""]*$" );
}

public static class Csv
{
    public static string Escape( string s )
    {
        if ( s.Contains( QUOTE ) )
            s = s.Replace( QUOTE, ESCAPED_QUOTE );

        if ( s.IndexOfAny( CHARACTERS_THAT_MUST_BE_QUOTED ) > -1 )
            s = QUOTE + s + QUOTE;

        return s;
    }

    public static string Unescape( string s )
    {
        if ( s.StartsWith( QUOTE ) && s.EndsWith( QUOTE ) )
        {
            s = s.Substring( 1, s.Length - 2 );

            if ( s.Contains( ESCAPED_QUOTE ) )
                s = s.Replace( ESCAPED_QUOTE, QUOTE );
        }

        return s;
    }


    private const string QUOTE = "\"";
    private const string ESCAPED_QUOTE = "\"\"";
    private static char[] CHARACTERS_THAT_MUST_BE_QUOTED = { ',', '"', '\n' };
}
harpo
sumber
2
Anda mungkin juga perlu menerjemahkan \ r \ n untuk kepatuhan windows, tergantung pada aplikasi Anda.
Mandrake
3
@NadaNaeem, mau jelaskan?
Harpo
itu tidak menghitung item dalam baris file csv dengan benar, itu tidak berurusan dengan baik dengan koma di bidang dan pengembalian keberanian dan ketukan
Nada N. Hantouli
-1 OP tidak menentukan bahasa yang membuat file. Jika ada programmer lain datang ke sini mencari solusi dalam bahasa apa pun selain C #, mereka tidak akan menemukan solusi yang dapat mereka gunakan dalam jawaban ini.
Ben Leggiero
8
@ BenC.R.Leggiero, maka saya kira Anda juga harus menurunkan pertanyaan, karena tidak dapat dijawab oleh standar Anda. Seperti itu, kode berjumlah implementasi formal dari spesifikasi sederhana, dan dapat dengan mudah diterjemahkan ke bahasa yang umum digunakan.
harpo
395

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:

Bidang yang berisi penghentian baris (CRLF), tanda kutip ganda, dan koma harus dilampirkan dalam tanda kutip ganda.

http://tools.ietf.org/html/rfc4180

Jadi, untuk memiliki nilai foodan bar,baz, Anda melakukan ini:

foo,"bar,baz"

Persyaratan penting lainnya untuk dipertimbangkan (juga dari spesifikasi):

Jika tanda kutip ganda digunakan untuk menyertakan bidang, maka tanda kutip ganda yang muncul di dalam bidang harus diloloskan dengan mendahului dengan tanda kutip ganda lainnya. Sebagai contoh:

"aaa","b""bb","ccc"
Corey Trager
sumber
120
"Kolom yang berisi penghentian baris (CRLF), tanda kutip ganda, dan koma harus diapit tanda kutip ganda."
Eli
42
"Jika tanda kutip ganda digunakan untuk menyertakan bidang, maka tanda kutip ganda yang muncul di dalam bidang harus diloloskan dengan mendahului dengan tanda kutip ganda."
C. Dragon 76
11
Tidak benar-benar spek, tapi mungkin masih berguna. Dikatakan ... "Tidak ada spesifikasi formal yang ada, yang memungkinkan untuk berbagai interpretasi file CSV. Bagian ini mendokumentasikan format yang tampaknya diikuti oleh sebagian besar implementasi."
Justin Clarke
5
Selain itu, jangan lupa bahwa, terlepas dari namanya, nilai CSV di baris dapat dipisahkan tidak hanya dengan koma - setidaknya pada platform Windows. Hal ini tergantung pada pengaturan regional saat ini (intl.cpl di baris perintah, "Setelan lanjutan"), khususnya, daftar pemisah: System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator.
lxa
4
Harap cantumkan informasi yang relevan dalam jawaban ini, selain tautannya, ke A) Hapus sebagian besar komentar di atas (dan milik saya), B) Simpan lebih banyak orang daripada penjawab waktu untuk membuka halaman lain dan temukan yang relevan data, C) Mencegah Busuk Tautan.
user66001
76

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:

test
list, of, items
"go" he said

akan dikodekan sebagai:

test
"list, of, items"
"""go"" he said"

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.

Robert Gamble
sumber
40

Letakkan tanda kutip ganda di sekitar string. Itulah yang dilakukan Excel pada umumnya .

Ala Eli,

Anda lolos dari penawaran ganda sebagai dua penawaran ganda. Misalnya "test1", "foo" "bar", "test2"

Joe Phillips
sumber
pada dasarnya konsep yang sama seperti Pengenal yang dikutip
Bob The Janitor
1
Anda lolos dari kuotasi ganda sebagai dua kuotasi ganda. Misalnya "test1", "foo" "bar", "test2"
Eli
Hanya menempatkan tanda kutip ganda di string tidak bekerja ketika tanda "diikuti segera oleh koma
MondKin
9

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:

data, lebih banyak data, lebih banyak data \, bahkan, namun lebih banyak lagi

Anda tidak harus mencoba mencocokkan kutipan, dan Anda memiliki lebih sedikit pengecualian untuk diuraikan. Ini menyederhanakan kode Anda juga.

Adam Jaskiewicz
sumber
3
Cepat dan kotor tetapi tidak berfungsi jika Anda benar-benar memiliki entri yang berisi "\,"
Sarp Kaya
1
Sarp, itu sebabnya double \\ adalah garis miring terbalik, karena sekarang menjadi karakter khusus lain.
Grungondola
1
Ini berfungsi, tetapi bukan CSV. Itu DSV .
TRiG
8

Ada perpustakaan yang tersedia melalui nuget untuk menangani hampir semua CSV (.net) yang terbentuk dengan baik - CsvHelper

Contoh untuk memetakan ke kelas:

var csv = new CsvReader( textReader );
var records = csv.GetRecords<MyClass>();

Contoh untuk membaca masing-masing bidang:

var csv = new CsvReader( textReader );
while( csv.Read() )
{
    var intField = csv.GetField<int>( 0 );
    var stringField = csv.GetField<string>( 1 );
    var boolField = csv.GetField<bool>( "HeaderName" );
}

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:

var csv = new CsvReader( textReader );
csv.Configuration.Delimiter = "#";
csv.Configuration.Quote = ''';
// read the file however meets your needs

Lebih Banyak Dokumentasi

NikolaiDante
sumber
3
Akan lebih baik jika Anda menyertakan contoh bagaimana menggunakan CsvHelperperpustakaan untuk menyelesaikan masalah OP.
George Stocker
Mengapa hampir semua yang ada di .Net harus menjadi "Pembantu" ... kata itu hampir tidak berarti ... seperti "Manajer".
bytedev
5

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):

if (_expectedDataLength > 0 && values.Length != _expectedDataLength) 
throw new DataLengthException(string.Format("Expected {0} columns when splitting csv, got {1}", _expectedDataLength, values.Length));

Ini dapat disuntikkan melalui konstruktor:

public CsvReader(string fileName, int expectedDataLength = 0) : this(new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
    _expectedDataLength = expectedDataLength;
}
MikeDub
sumber
Bagaimana cara Anda menangani baris Header? saya mencoba memetakan objek csv ke C # yang semuanya tipe, tetapi baris header
memecahnya
Tidak [^""]sama dengan [^"]? Duplikasi karakter di dalam spesifikasi kelas karakter adalah mubazir, bukan?
Minh Tran
4

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.TextFieldParserkelas untuk mem-parsing file CSV Berikut adalah contoh kode:

 Dim parser As TextFieldParser = New TextFieldParser("C:\mar0112.csv")
 parser.TextFieldType = FieldType.Delimited
 parser.SetDelimiters(",")      

   While Not parser.EndOfData         
      'Processing row             
      Dim fields() As String = parser.ReadFields         
      For Each field As String In fields             
         'TODO: Process field                   

      Next      
      parser.Close()
   End While 
mvilaskumar
sumber
Ya, ini adalah kelas yang sangat berguna di namespace yang agak disayangkan ;-). Untuk menjawab pertanyaan awal, Anda juga harus mengatur parser.HasFieldsEnclosedInQuotes = true;dan file input harus menyertakan bidang yang berisi koma dalam tanda kutip sesuai dengan spesifikasi CSV - excel sudah melakukannya.
Christopher King
4

Jika Anda menggunakan sistem * nix , memiliki akses ke seddan 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:

sed -r 's/([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*)/\1"\2"\3/' inputfile

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.

masukkan deskripsi gambar di sini

Dalam kombinasi dengan --in-placeopsi- Anda dapat menerapkan perubahan ini langsung ke file.

Untuk "membangun" regex yang tepat, ada prinsip sederhana untuk diikuti:

  1. Untuk setiap bidang dalam CSV Anda yang datang sebelum bidang dengan koma yang tidak diinginkan, Anda menulis satu [^,]*,dan menempatkan semuanya bersama-sama dalam kelompok penangkapan.
  2. Untuk bidang yang berisi koma yang tidak diinginkan yang Anda tulis (.*).
  3. Untuk setiap bidang setelah bidang dengan koma yang tidak diinginkan, Anda menulis satu ,.* 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.

([^,]*)(,.*)                     #first field, regex
"\1"\2                           #first field, substitution

(.*,)([^,]*)                     #last field, regex
\1"\2"                           #last field, substitution


([^,]*,)(.*)(,.*,.*,.*)          #second field (out of five fields)
([^,]*,[^,]*,)(.*)(,.*)          #third field (out of four fields)
([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*) #fourth field (out of six fields)

Jika Anda ingin menghapus koma yang tidak diinginkan dengan menambahkan sedtanda kutip, lihat jawaban ini .

Basti M
sumber
3

Jika Anda merasa ingin menciptakan kembali roda, yang berikut ini mungkin cocok untuk Anda:

public static IEnumerable<string> SplitCSV(string line)
{
    var s = new StringBuilder();
    bool escaped = false, inQuotes = false;
    foreach (char c in line)
    {
        if (c == ',' && !inQuotes)
        {
            yield return s.ToString();
            s.Clear();
        }
        else if (c == '\\' && !escaped)
        {
            escaped = true;
        }
        else if (c == '"' && !escaped)
        {
            inQuotes = !inQuotes;
        }
        else
        {
            escaped = false;
            s.Append(c);
        }
    }
    yield return s.ToString();
}
Neil
sumber
3

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:

| American      | Europe        |
| ------------- | ------------- |
| 0.5           | 0,5           |
| 3.14159265359 | 3,14159265359 |
| 17.54         | 17,54         |
| 175,186.15    | 175.186,15    |

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 .

H. Pauwelyn
sumber
2

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.

Phil
sumber
1

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

Konstantine Nikka-Sher Piterma
sumber
1

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.

Jonathan Wood
sumber
0

Karena ini adalah praktik umum, mari kita mulai dari aturan praktis:

  1. Jangan gunakan CSV, gunakan XML dengan perpustakaan untuk membaca & menulis file xml.

  2. 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.

Piotr Czapla
sumber
12
XML tidak selalu jawabannya. CSV adalah format yang tepat untuk pekerjaan saat Anda memiliki banyak data tabular yang padat (yaitu spreadsheet). Tag-tag itu memperkenalkan banyak overhead, dan jika setiap baris memiliki format yang identik, tidak perlu secara eksplisit tentang apa yang diwakili oleh setiap nilai. XML bagus jika Anda memiliki data hierarkis yang rumit, atau catatan dengan bidang opsional. Itu tidak selalu terjadi.
Adam Jaskiewicz
Secara teori, "tag" memperkenalkan sedikit overhead tetapi saya tidak bisa memikirkan aplikasi kehidupan nyata di mana ia mulai menjadi masalah. Apakah Anda punya contoh praktis? Untuk bekerja pada data seseorang harus menggunakan database, bukan csv. jika kita berbicara tentang serialisasi data (cadangan, pertukaran data), apakah akan masalah jika parsing membutuhkan waktu seminggu, bukannya 5 hari?
Piotr Czapla
2
Pada dasarnya, situasi apa pun di mana Anda memiliki data yang paling baik diwakili oleh tabel. Katakanlah Anda memiliki data dari selusin sensor berbeda yang sering Anda sampel, dan Anda merekam cap waktu dan nilai masing-masing sensor pada waktu itu. Setiap record identik: cap waktu, sensor0, sensor1, ... sensor11. XML bagus untuk merepresentasikan data yang kompleks dan tidak beraturan, tetapi formatnya agak berat yang tidak cocok untuk setiap situasi. Kiss
Adam Jaskiewicz
10
Beberapa orang melihat masalah, dan mereka berkata "Saya tahu, saya akan menggunakan XML!" Sekarang mereka memiliki dua masalah.
Adam Jaskiewicz
Saya sepenuhnya setuju bahwa xml bukan jawaban untuk semuanya. Terutama itu tidak cocok sebagai pengganti basis data atau untuk file konfigurasi. Tapi di sini pertanyaannya adalah tentang pertukaran data yang dirancang untuk XML.
Piotr Czapla
0

Anda dapat membaca file csv seperti ini.

ini memanfaatkan pemisahan dan merawat ruang.

ArrayList List = new ArrayList();
static ServerSocket Server;
static Socket socket;
static ArrayList<Object> list = new ArrayList<Object>();


public static void ReadFromXcel() throws FileNotFoundException
{   
    File f = new File("Book.csv");
    Scanner in = new Scanner(f);
    int count  =0;
    String[] date;
    String[] name;
    String[] Temp = new String[10];
    String[] Temp2 = new String[10];
    String[] numbers;
    ArrayList<String[]> List = new ArrayList<String[]>();
    HashMap m = new HashMap();

         in.nextLine();
         date = in.nextLine().split(",");
         name = in.nextLine().split(",");
         numbers = in.nextLine().split(",");
         while(in.hasNext())
         {
             String[] one = in.nextLine().split(",");
             List.add(one);
         }
         int xount = 0;
         //Making sure the lines don't start with a blank
         for(int y = 0; y<= date.length-1; y++)
         {
             if(!date[y].equals(""))
             {   
                 Temp[xount] = date[y];
                 Temp2[xount] = name[y];
                 xount++;
             }
         }

         date = Temp;
         name =Temp2;
         int counter = 0;
         while(counter < List.size())
         {
             String[] list = List.get(counter);
             String sNo = list[0];
             String Surname = list[1];
             String Name = list[2];
             for(int x = 3; x < list.length; x++)
             {           
                 m.put(numbers[x], list[x]);
             }
            Object newOne = new newOne(sNo, Name, Surname, m, false);
             StudentList.add(s);
             System.out.println(s.sNo);
             counter++;
         }
Eric
sumber
0

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:

// Replace special CSV characters with single low-9 quotation mark
func Scrub(a interface{}) string {
    s := fmt.Sprint(a)
    s = strings.Replace(s, ",", "‚", -1)
    s = strings.Replace(s, ";", "‚", -1)
    return s
}

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

l3x
sumber
0

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

URLEncoder.encode(myString,"UTF-8"); //to encode
URLDecoder.decode(myEncodedstring, "UTF-8"); //to decode

Saya tahu ini adalah solusi yang sangat umum dan mungkin tidak ideal untuk situasi di mana pengguna ingin melihat konten file csv, secara manual.

hariszhr
sumber
0

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'.

// The below two lines will split the columns as well as trim the DBOULE QUOTES around values but NOT within them
    string trimmedLine = line.Trim(new char[] { '\"' });
    List<string> values = trimmedLine.Split(new string[] { "\",\"" }, StringSplitOptions.None).ToList();
pengguna1451111
sumber
1
Mengapa kode saya tidak pernah ditampilkan dalam berbagai warna di StackOverflow? Saya indentasi oleh empat spasi.
user1451111
0

Solusi paling sederhana yang saya temukan adalah yang digunakan LibreOffice:

  1. Ganti semua literal " dengan
  2. Letakkan tanda kutip ganda di sekitar string Anda

Anda juga bisa menggunakan yang digunakan Excel:

  1. Ganti semua literal " dengan""
  2. Letakkan tanda kutip ganda di sekitar string Anda

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 string hello",world, seperti yang dibaca CSV:

"hello",world"

Yang diartikan sebagai baris dengan dua kolom: hellodanworld"

MondKin
sumber
1
Menurut aturan standar, bidang apa pun yang berisi karakter terbelah atau kutipan dikelilingi oleh tanda kutip, dan setiap kutipan di dalam yang digandakan, sehingga tidak ada masalah. hello",worldBidang Anda hanya perlu disimpan sebagai "hello"",world", yang dapat diurai 100% dengan benar.
Nyerguds
0
    public static IEnumerable<string> LineSplitter(this string line, char 
         separator, char skip = '"')
    {
        var fieldStart = 0;
        for (var i = 0; i < line.Length; i++)
        {
            if (line[i] == separator)
            {
                yield return line.Substring(fieldStart, i - fieldStart);
                fieldStart = i + 1;
            }
            else if (i == line.Length - 1)
            {
                yield return line.Substring(fieldStart, i - fieldStart + 1);
                fieldStart = i + 1;
            }

            if (line[i] == '"')
                for (i++; i < line.Length && line[i] != skip; i++) { }
        }

        if (line[line.Length - 1] == separator)
        {
            yield return string.Empty;
        }
    }
Rajat26
sumber
0

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

function csv_to_array($filename='', $delimiter=',')
{
    if(!file_exists($filename) || !is_readable($filename))
        return FALSE;

    $header = NULL;
    $data = array();
    if (($handle = fopen($filename, 'r')) !== FALSE)
    {
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
        {
            if(!$header)
                $header = $row;
            else
                $data[] = array_combine($header, $row);
        }
        fclose($handle);
    }
    return $data;
}
Vir
sumber
0

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.

paragraf patel
sumber
0

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"

pengguna1247591
sumber
-1

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.

jamesdeath123
sumber
Siapa bilang mereka punya Excel? Bahkan siapa yang mengatakan bahwa ini adalah manusia yang sedang mengunggah? ...
bytedev
-3

Gunakan karakter tab (\ t) untuk memisahkan bidang.

Pierre
sumber
4
-1 Hebat sampai seseorang menggunakan tab dalam nilainya, kemudian langsung kembali ke masalah yang ditanyakan orang tersebut. Swaping satu pembatas char untuk yang lain tidak akan menyelesaikan masalah.
bytedev
Omong kosong. Orang tidak dapat memasukkan tab di input data mereka. Dalam sebagian besar bentuk, itu hanya memindahkan titik entri data ke bidang berikutnya.
Pierre
6
"Orang-orang tidak dapat memasukkan tab pada input data mereka" .... apakah Anda serius ?? A) tentu saja seseorang bisa meletakkan tab di bidang input B) yang mengatakan itu adalah GUI data berasal? C) siapa bilang bahkan manusia yang memasukkan data?
bytedev