基于逗号分割文本

时间:2011-11-13 13:57:27

标签: c# string csv split

  

可能重复:
  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出现在一个列中。我该如何解决这个问题?

4 个答案:

答案 0 :(得分:3)

因为您要忽略引号之间的记录中的,,所以执行此操作的唯一方法是解析该行。

使用布尔值循环遍历字符串(如果在引号之间,则为true),然后手工构建列表/数组,仅在布尔值为false时生成新项。

正如安德烈亚斯在评论中指出的那样,这个问题有完整的来源:

Dealing with commas in a CSV file

答案 1 :(得分:2)

可能有点矫枉过正,但JET的OLE DB提供程序也可以读取CSV文件,还可以为每列提供正确类型的数据。示例用于此question

如果你想手工解析它(应该是可行的),你可以参考CSV上的维基百科article,其中详细说明了语法。

答案 2 :(得分:1)

这个辅助方法可以解决这个问题:

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, ',');

答案 3 :(得分: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);
        }
    }
}

<强> RESULT

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