2011-11-13 2 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

Этот вспомогательный метод делает трюк:

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-файлов. (хотя это не позволяет использовать метод «Сплит») – smartcaveman

3

Поскольку вы хотите игнорировать , в записях, находящихся между кавычками, единственный способ сделать это - проанализировать линию.

Петля по строке с булевым (true, если между кавычками), а затем вручную создайте список/массив, создавая новый элемент, когда логическое значение false.

Как Andreas указывает в комментариях есть полный источник, расположенный в этом вопросе:

Dealing with commas in a CSV file

+0

+1, для ссылки – smartcaveman

2

Может быть излишним, но поставщик OLE DB для JET также может читать CSV файлов, а также может дать вы данные о соответствующих типах для каждого столбца. Пример использования в этом question.

Если вы хотите разобрать его вручную (что должно быть выполнимо), вы можете обратиться к Wikipedia article на CSV, который немного детализирует синтаксис.

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" 
Смежные вопросы