2009-06-26 19 views
2

Wie teilt man die CSV-Datei in cis auf? Und wie zeigt man das an?Komma-getrennte Werte (CSV) teilen

+1

Wichtige Lesung in Bezug auf CSV: http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm # CSCIations – Stobor

+1

Nicht sehr präzise, ​​Ihre Frage ... wenn Sie mehr Details geben, erhalten Sie mehr nützliche Antworten. – Benjol

+0

einfach, ich meine, ich muss eine Zeichenfolge lesen, die ich eingegeben habe, und aufteilen und speichert in einem Array. – MAC

Antwort

1

Ich hatte das Ergebnis für meine Abfrage. Es ist so einfach wie ich eine Datei mit io.file gelesen hatte. und der gesamte Text wird in einer Zeichenfolge gespeichert. Danach habe ich mich mit einem Separator getrennt. Der Code ist unten gezeigt.

using System; 
using System.Collections.Generic; 
using System.Text; 

namespace CSV 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      string csv = "user1, user2, user3,user4,user5"; 

      string[] split = csv.Split(new char[] {',',' '}); 
      foreach(string s in split) 
      { 
       if (s.Trim() != "") 
        Console.WriteLine(s); 
      } 
      Console.ReadLine(); 
     } 
    } 
} 
+0

Ich bin froh, dass Sie eine Lösung gefunden haben. Wenn Sie sich detaillierter mit CSV-Dateien befassen möchten, sollten Sie sich einige der anderen hier veröffentlichten Methoden und Links ansehen. Es scheint, als ob Ihnen das genaue Format Ihrer CSV-Dateien bekannt ist. Beachten Sie auch die Dateigrößen. Eine Zeichenfolge, die die gesamte CSV-Datei darstellt, ist bis zu einigen Megabyte zulässig. Wenn Sie jedoch große Dateien verwenden, sollten Sie sich den von Vinko veröffentlichten Codeproject-Link ansehen. Auch wenn Sie sie in diesem Beispiel nicht verwenden müssen, sollten Sie sicherstellen, dass Sie wissen, was StringSplitOptions und der "count" -Parameter für String.Split tun. :-) – maxwellb

1

lesen Sie die Datei zu einem Zeitpunkt eine Zeile, dann ...

foreach (String line in line.Split(new char[] { ',' })) 
    Console.WriteLine(line); 
+0

Leider funktioniert das nicht, wenn die Werte eingebettete Kommas oder Felder in Anführungszeichen enthalten. Versuchen Sie stattdessen die TextFieldParser-Klasse. – Graham

+0

Ja, ich habe das kurz nach der Bereitstellung dieses Beispiels rela- lisiert>. < Es ist jedoch leicht zu überwinden, behalte nur eine Zählung der Anzahl von 's und spalte nur, wenn es eine gerade Zahl gab, und entkomme keine :) Also denke ich, dass Sie die Zeichenfolge vor dem Teilen in Token zerlegen müssten.Diese Komplexität ist es, mit der 3rd Party Bibliotheken helfen. – Nippysaurus

5

anzeigen, wo? Beim Teilen ist der beste Weg, eine gute Bibliothek zu verwenden.

This library ist ziemlich gut, ich kann es herzlich empfehlen.

Die Probleme naive Methoden besteht darin, dass die in der Regel nicht, da jede Menge Überlegungen sind, ohne auch nur über Leistung zu denken:

  • Was passiert, wenn der Text durch Kommata
  • Unterstützung für die vielen bestehenden Formaten (getrennt enthält Semikolon oder Text in Anführungszeichen oder einfache Anführungszeichen, etc.)
  • und viele andere
1

Dies ist ein CSV-Parser ich gelegentlich nutzen.

Verbrauch: (. DgvMyView ist ein Datagrid-Typ)

CSVReader reader = new CSVReader("C:\MyFile.txt"); 
reader.DisplayResults(dgvMyView); 

Klasse:

using System.IO; 
using System.Text.RegularExpressions; 
using System.Windows.Forms;  
public class CSVReader 
{ 
    private const string ESCAPE_SPLIT_REGEX = "({1}[^{1}]*{1})*(?<Separator>{0})({1}[^{1}]*{1})*"; 
    private string[] FieldNames; 
    private List<string[]> Records; 
    private int ReadIndex; 

    public CSVReader(string File) 
    { 
     Records = new List<string[]>(); 
     string[] Record = null; 
     StreamReader Reader = new StreamReader(File); 
     int Index = 0; 
     bool BlankRecord = true; 

     FieldNames = GetEscapedSVs(Reader.ReadLine()); 
     while (!Reader.EndOfStream) 
     { 
      Record = GetEscapedSVs(Reader.ReadLine()); 
      BlankRecord = true; 
      for (Index = 0; Index <= Record.Length - 1; Index++) 
      { 
       if (!string.IsNullOrEmpty(Record[Index])) BlankRecord = false; 
      } 
      if (!BlankRecord) Records.Add(Record); 
     } 
     ReadIndex = -1; 
     Reader.Close(); 
    } 

    private string[] GetEscapedSVs(string Data) 
    { 
     return GetEscapedSVs(Data, ",", "\""); 
    } 
    private string[] GetEscapedSVs(string Data, string Separator, string Escape) 
    { 
     string[] Result = null; 
     int Index = 0; 
     int PriorMatchIndex = 0; 
     MatchCollection Matches = Regex.Matches(Data, string.Format(ESCAPE_SPLIT_REGEX, Separator, Escape)); 

     Result = new string[Matches.Count]; 


     for (Index = 0; Index <= Result.Length - 2; Index++) 
     { 
      Result[Index] = Data.Substring(PriorMatchIndex, Matches[Index].Groups["Separator"].Index - PriorMatchIndex); 
      PriorMatchIndex = Matches[Index].Groups["Separator"].Index + Separator.Length; 
     } 
     Result[Result.Length - 1] = Data.Substring(PriorMatchIndex); 

     for (Index = 0; Index <= Result.Length - 1; Index++) 
     { 
      if (Regex.IsMatch(Result[Index], string.Format("^{0}[^{0}].*[^{0}]{0}$", Escape))) Result[Index] = Result[Index].Substring(1, Result[Index].Length - 2); 
      Result[Index] = Result[Index].Replace(Escape + Escape, Escape); 
      if (Result[Index] == null) Result[Index] = ""; 
     } 

     return Result; 
    } 

    public int FieldCount 
    { 
     get { return FieldNames.Length; } 
    } 

    public string GetString(int Index) 
    { 
     return Records[ReadIndex][Index]; 
    } 

    public string GetName(int Index) 
    { 
     return FieldNames[Index]; 
    } 

    public bool Read() 
    { 
     ReadIndex = ReadIndex + 1; 
     return ReadIndex < Records.Count; 
    } 


    public void DisplayResults(DataGridView DataView) 
    { 
     DataGridViewColumn col = default(DataGridViewColumn); 
     DataGridViewRow row = default(DataGridViewRow); 
     DataGridViewCell cell = default(DataGridViewCell); 
     DataGridViewColumnHeaderCell header = default(DataGridViewColumnHeaderCell); 
     int Index = 0; 
     ReadIndex = -1; 

     DataView.Rows.Clear(); 
     DataView.Columns.Clear(); 

     for (Index = 0; Index <= FieldCount - 1; Index++) 
     { 
      col = new DataGridViewColumn(); 
      col.CellTemplate = new DataGridViewTextBoxCell(); 
      header = new DataGridViewColumnHeaderCell(); 
      header.Value = GetName(Index); 
      col.HeaderCell = header; 
      DataView.Columns.Add(col); 
     } 

     while (Read()) 
     { 
      row = new DataGridViewRow(); 
      for (Index = 0; Index <= FieldCount - 1; Index++) 
      { 
       cell = new DataGridViewTextBoxCell(); 
       cell.Value = GetString(Index).ToString(); 
       row.Cells.Add(cell); 
      } 
      DataView.Rows.Add(row); 
     } 
    } 
} 
11

Ich habe für ein C# Projekt der TextFieldParser Class im Microsoft.VisualBasic.FileIO Namespace I arbeite daran. Es behandelt Komplikationen wie eingebettete Kommas oder Felder, die in Anführungszeichen eingeschlossen sind. Es gibt eine Zeichenkette [] zurück und kann zusätzlich zu CSV-Dateien auch zum Parsen von jeder Art von strukturierter Textdatei verwendet werden.

+0

Interessant. Ich habe noch nie hier nachgesehen. Ich habe kürzlich eine komplette CSV-Klasse in C# geschrieben, und dies Ich hätte die Zeilenumbrüche in ~ 's umgewandelt, und nun könnten Kommas nur im letzten Feld vorkommen, also habe ich den maxentries-Parameter von String.Split verwendet, um das gesamte letzte Feld, Kommas und alles zu erfassen, aber ich' ll muss sich diese Klasse ansehen Danke für den Link – maxwellb

+1

Bestellung für 'common' Funktionalität 1) Core Framework 2) Extended Framework 3) Open Source-Bibliothek 4) Günstige bezahlt für die Bibliothek 5) Schreiben Sie es selbst – AndyM

0

Die folgende Funktion nimmt eine Zeile aus einer CSV-Datei und teilt sie in ein List<string>.

Argumente:
Zeichenfolge Linie = die Linie
String TEXTQUALIFIER aufzuspalten = welche (wenn überhaupt) Textbegrenzer (dh "" oder "\"“oder """)
char delim = der Feldtrennzeichen (dh '' oder '' oder '|' oder '\ t')
int colCount = die erwartete Anzahl von Feldern (0 bedeutet nicht prüfen)

Beispiel Nutzung:

List<string> fields = SplitLine(line, "\"", ',', 5); 
// or 
List<string> fields = SplitLine(line, "'", '|', 10); 
// or 
List<string> fields = SplitLine(line, "", '\t', 0); 

Funktion:

private List<string> SplitLine(string line, string textQualifier, char delim, int colCount) 
{ 
    List<string> fields = new List<string>(); 
    string origLine = line; 

    char textQual = '"'; 
    bool hasTextQual = false; 
    if (!String.IsNullOrEmpty(textQualifier)) 
    { 
     hasTextQual = true; 
     textQual = textQualifier[0];    
    } 

    if (hasTextQual) 
    { 
     while (!String.IsNullOrEmpty(line)) 
     { 
      if (line[0] == textQual) // field is text qualified so look for next unqualified delimiter 
      { 
       int fieldLen = 1; 
       while (true) 
       { 
        if (line.Length == 2) // must be final field (zero length) 
        { 
         fieldLen = 2; 
         break; 
        } 
        else if (fieldLen + 1 >= line.Length) // must be final field 
        { 
         fieldLen += 1; 
         break; 
        } 
        else if (line[fieldLen] == textQual && line[fieldLen + 1] == textQual) // escaped text qualifier 
        { 
         fieldLen += 2; 
        } 
        else if (line[fieldLen] == textQual && line[fieldLen + 1] == delim) // must be end of field 
        { 
         fieldLen += 1; 
         break; 
        } 
        else // not a delimiter 
        { 
         fieldLen += 1; 
        } 
       } 
       string escapedQual = textQual.ToString() + textQual.ToString(); 
       fields.Add(line.Substring(1, fieldLen - 2).Replace(escapedQual, textQual.ToString())); // replace escaped qualifiers 
       if (line.Length >= fieldLen + 1) 
       { 
        line = line.Substring(fieldLen + 1); 
        if (line == "") // blank final field 
        { 
         fields.Add(""); 
        } 
       } 
       else 
       { 
        line = ""; 
       } 
      } 
      else // field is not text qualified 
      { 
       int fieldLen = line.IndexOf(delim); 
       if (fieldLen != -1) // check next delimiter position 
       { 
        fields.Add(line.Substring(0, fieldLen)); 
        line = line.Substring(fieldLen + 1); 
        if (line == "") // final field must be blank 
        { 
         fields.Add(""); 
        } 
       } 
       else // must be last field 
       { 
        fields.Add(line); 
        line = ""; 
       } 
      } 
     } 
    } 
    else // if there is no text qualifier, then use existing split function 
    { 
     fields.AddRange(line.Split(delim)); 
    }  

    if (colCount > 0 && colCount != fields.Count) // count doesn't match expected so throw exception 
    { 
     throw new Exception("Field count was:" + fields.Count.ToString() + ", expected:" + colCount.ToString() + ". Line:" + origLine); 

    } 
    return fields; 
} 
2

Import Micorosoft.VisualBasic als Referenz (ich weiß, es ist nicht so schlimm) und verwenden Microsoft.VisualBasic.FileIO.TextFieldParser - diese Griffe CSV-Dateien sehr gut, und kann in jeder .NET-Sprache verwendet werden.

+0

Warum die -1? Das ist ein großartiger CSV-Parser ... – cjk

Verwandte Themen