C # Regex Split – Vírgulas fora de citações

Eu tenho um monte de seqüências de caracteres (segmentos de código SQL, na verdade) com o seguinte formato:

('ABCDEFG', 123542, 'XYZ 99,9') 

e eu preciso dividir essa string, usando C #, para obter:

  • ‘ABCDEFG’
  • 123542
  • ‘XYZ 99,9’

Eu estava originalmente usando um simples Split(',') , mas desde que a vírgula dentro do último parâmetro está causando estragos na saída eu preciso usar o Regex para obtê-lo. O problema é que eu ainda sou muito obcecado em expressões regulares e eu não consigo quebrar o padrão, principalmente porque dentro dessa string os parâmetros numéricos e alfanuméricos podem existir a qualquer momento …

O que eu poderia usar para dividir essa string de acordo com cada vírgula fora das aspas? Felicidades

Você pode dividir em todas as vírgulas, que têm um número par de citações seguindo-as, usando o seguinte Regex para encontrá-las:

 ",(?=(?:[^']*'[^']*')*[^']*$)" 

Você usaria como

 var result = Regex.Split(samplestring, ",(?=(?:[^']*'[^']*')*[^']*$)"); 

embora eu também goste de um desafio algumas vezes, mas na verdade isso não é um. por favor leia este artigo http://secretgeek.net/csv_trouble.asp e depois vá em http://www.filehelpers.com/

[Edit1, 3]: ou talvez este artigo também possa ajudar (o link mostra apenas alguns códigos de exemplo VB.Net, mas ainda assim você pode usá-lo com o C #!): http://msdn.microsoft.com/en-us /library/cakac7e6.aspx

Eu tentei fazer o exemplo para c # (adicionar referência ao Microsoft.VisualBasic ao seu projeto)

 using System; using System.IO; using Microsoft.VisualBasic.FileIO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { TextReader reader = new StringReader("('ABCDEFG', 123542, 'XYZ 99,9')"); TextFieldParser fieldParser = new TextFieldParser(reader); fieldParser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited; fieldParser.SetDelimiters(","); String[] currentRow; while (!fieldParser.EndOfData) { try { currentRow = fieldParser.ReadFields(); foreach(String currentField in currentRow) { Console.WriteLine(currentField); } } catch (MalformedLineException e) { Console.WriteLine("Line {0} is not valid and will be skipped.", e); } } } } } 

[Edit2]: encontrado outro que poderia ser de ajuda aqui: http://www.codeproject.com/KB/database/CsvReader.aspx

– reinhard

 //this regular expression splits string on the separator character NOT inside double quotes. //separatorChar can be any character like comma or semicolon etc. //it also allows single quotes inside the string value: eg "Mike's Kitchen","Jane's Room" Regex regx = new Regex(separatorChar + "(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))"); string[] line = regx.Split(string to split); 

… ou você poderia ter instalado o pacote NuVard LumenWorks CsvReader e feito algo como abaixo, onde eu li um arquivo csv que tem conteúdo como por exemplo

 "hello","how","hello, how are you" "hi","hello","greetings" ... 

e processá-lo assim

 public static void ProcessCsv() { var filename = @"your_file_path\filename.csv"; DataTable dt = new DataTable("MyTable"); List product_codes = new List(); using (CsvReader csv = new CsvReader(new StreamReader(filename), true)) { int fieldCount = csv.FieldCount; string[] headers = csv.GetFieldHeaders(); for (int i = 0; i < headers.Length; i++) { dt.Columns.Add(headers[i], typeof(string)); } while (csv.ReadNextRecord()) { DataRow dr = dt.NewRow(); for (int i = 0; i < fieldCount; i++) { product_codes.Add(csv[i]); dr[i] = csv[i]; } dt.Rows.Add(dr); } } } 

Tente (hackeado de Jens ‘) no método split:

",(?:.*?'[^']*?')"

ou apenas adicionar pontos de interrogação após o Jens ‘*’ s, o que torna mais preguiçoso do que ganancioso.