2009-06-26 191 views
2

如何在c sharp中分割CSV文件?以及如何显示这个?分割逗号分隔值(CSV)

+1

关于CSV的重要阅读:http://www.creativyst.com/Doc/Articles/CSV/CSV01。htm#CSVariations – Stobor 2009-06-26 05:57:12

+1

不是很精确,你的问题......如果你提供更多的细节,你会得到更有用的答案。 – Benjol 2009-06-26 06:02:25

+0

简单地说,我的意思是我必须读取我输入的字符串,并将其分解并存储到数组中。 – MAC 2009-06-26 06:06:28

回答

1

我已经得到了我的查询结果。它就像我用io.file读取文件一样简单。并将所有文本存储到一个字符串中。之后,我与一个分离器分手。代码如下所示。

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(); 
     } 
    } 
} 
1

读取文件的一行的时间,然后...

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

显示在哪里?关于分割,最好的方法是使用一个好的库来达到这个效果。

This library很不错,我可以诚恳地推荐它。

用天真的方法的问题是,通常会失败,有吨的考虑,甚至没有考虑性能:

如果
  • 文本包含逗号的许多现有格式
  • 支持(通过分离分号或文字的报价,或单引号等包围)
  • 和许多其他
1

这是一个CSV解析器我偶尔使用。

用法:(dgvMyView是一个DataGrid型)

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

类:

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

我一直在使用TextFieldParser Class在Microsoft.VisualBasic.FileIO命名空间C#项目我正在努力。它将处理复杂的问题,如嵌入逗号或用引号括起来的字段等。它返回一个字符串[],除了CSV文件外,还可以用于解析任何类型的结构化文本文件。

0

下面的函数从CSV文件中取出一行并将其分成一个List<string>

参数:
串线=行分裂
串TEXTQUALIFIER =什么(如果有的话)文本限定符(即, “” 或 “\””或 “”“)
炭DELIM =字段分隔符(即 '' 或 ';' 或 '|' 或 '\ T')
INT colCount =字段的预期数(0表示不检查)

实例:

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

功能:

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

导入Micorosoft.VisualBasic作为参考(我知道,它不是那么糟糕),并使用Microsoft.VisualBasic.FileIO.TextFieldParser - 这种处理CSV文件时效果很好,并且可以在任何.NET语言中使用。