【问题标题】:Splitting text based on comma [duplicate]基于逗号分割文本[重复]
【发布时间】:2011-12-28 01:28:50
【问题描述】:

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

【问题讨论】:

标签: c# string csv split


【解决方案1】:

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

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

正如 Andreas 在 cmets 中指出的那样,这个问题中有完整的来源:

Dealing with commas in a CSV file

【讨论】:

    【解决方案2】:

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

    如果你想手动解析(应该可行),你可以参考 CSV 上的 Wikipedia article,其中详细说明了语法。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • @Jaggu,Hogan 链接到的帖子中的源具有用于解析 CSV 文件的更好的通用解决方案。 (虽然它不允许你使用Split 方法)
      【解决方案4】:
      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"
      

      【讨论】:

        猜你喜欢
        • 2019-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        相关资源
        最近更新 更多