2011-11-13 106 views
0

可能重复:
CSV parser/reader for C#?拆分文本

我想用Split功能分割文本:

string str = "ZBEE10364,\"Cobler, CHARLOTTE J\",Whiskey,,Brandy,0:00:00,20110912,CHECK,2918,117.33,1,117.33,0,EDM0,Yu789"; 
string[] strArr = str.Split(','); 

这工作得很好,但"Cober"CHARLOTTE在不同的记录。我不想那样。这是一个CSV文件,当我用Excel打开它时,它完美地工作。

Cobler, CHARLOTTE J出现在一个列中。我该如何解决这个问题?

+7

如果它是一个CSV文件,使用一个适当的CSV解析器。 – BoltClock

+1

http://stackoverflow.com/questions/906841/csv-parser-reader-for-c – Vlad

+1

http://stackoverflow.com/questions/769621/dealing-with-commas-in-a-csv-file – Andreas

回答

1

这个helper方法的伎俩:

public static class StringSplitHelper{ 

    public static string[] SplitNonQuoted(this string str, char separator){ 
    if(string.IsNullOrEmpty(str)) return new string[]{}; 
    if(separator == '\"') throw new ArgumentException("Separator cannot be a quotation mark", "separator"); 
    List<string> fields = new List<string>(); 
    bool inQuotes = false; 
    StringBuilder sb = new StringBuilder(); 
    foreach(var c in str){ 
     if(c == '\"') 
     { 
      inQuotes = !inQuotes; 
     } 
     else if(c == separator){ 
      if(inQuotes) { 
       sb.Append(c); 
      } 
      else { 
       fields.Add(sb.ToString()); 
       sb.Clear(); 
      } 
     } 
     else{ 
      sb.Append(c); 
     } 
    } 
    return fields.ToArray(); 
    } 
} 

然后,而不是strArr = str.Split(',');, 做strArr = str.SplitNonQuoted(this string str, ',');

+0

@Jaggu,Hogan链接的帖子中的源代码在解析CSV文件时具有更好的通用解决方案**。 (尽管它不允许你使用“Split”方法) – smartcaveman

3

因为您想在引号之间的记录中忽略,,唯一的方法是解析行。

用布尔值(如果在引号之间为true)在字符串上循环,然后手动构建列表/数组,只在布尔值为false时创建新项目。

由于安德烈亚斯指出在评论中有完整的源位于这样一个问题:

Dealing with commas in a CSV file

+0

+1,链接 – smartcaveman

2

可能是矫枉过正,但OLE DB提供程序为Jet还可以读取CSV文件,也可以给你的每一列的正确类型的数据。在这个例子中使用question

如果你想手动解析它(这应该是可行的),你可以参考CSV上的维基百科article,它稍微详述了这个语法。

0
using System; 
using System.Text; 
using Microsoft.VisualBasic.FileIO; //Microsoft.VisualBasic.dll 
using System.IO; 

public class Sample { 
    static void Main(){ 
     string str = "ZBEE10364,\"Cobler, CHARLOTTE J\",Whiskey,,Brandy,0:00:00,20110912,CHECK,2918,117.33,1,117.33,0,EDM0,Yu789"; 
     string[] strArr = str.Split(','); 
     var reader = new StringReader(str); 
     using(var csvReader = new TextFieldParser(reader)){ 
      csvReader.SetDelimiters(new string[] {","}); 
      csvReader.HasFieldsEnclosedInQuotes = true; 
      strArr = csvReader.ReadFields(); 
     } 

     //check print 
     foreach(var item in strArr){ 
      Console.WriteLine("\"{0}\"",item); 
     } 
    } 
} 

结果

"ZBEE10364" 
"Cobler, CHARLOTTE J" 
"Whiskey" 
"" 
"Brandy" 
"0:00:00" 
"20110912" 
"CHECK" 
"2918" 
"117.33" 
"1" 
"117.33" 
"0" 
"EDM0" 
"Yu789"