Подтвердить что ты не робот

С# Regex Split - запятые вне кавычек

На самом деле у меня довольно много строк (сегменты кода SQL) со следующим форматом:

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

и мне нужно разбить эту строку, используя С#, чтобы получить:

  • 'АБВГДЕЖ'
  • 123542
  • 'XYZ 99,9'

Я изначально использовал простой Split(','), но поскольку эта запятая внутри последнего параметра вызывает хаос в выходе, мне нужно использовать Regex для его получения. Проблема в том, что я по-прежнему довольно noobish в регулярных выражениях, и я не могу раскалывать шаблон в основном потому, что внутри этой строки могут быть как численные, так и альфа-числовые параметры в любое время...

Что я могу использовать для разделения этой строки в соответствии с каждой запятой вне кавычек? Приветствия

4b9b3361

Ответ 1

Вы можете разделить на все запятые, у которых есть четное количество кавычек, следующих за ними, используя следующее Regex, чтобы найти их:

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

Вы бы использовали его как

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

Ответ 2

//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: e.g. "Mike Kitchen","Jane Room"
Regex regx = new Regex(separatorChar + "(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))"); 
string[] line = regx.Split(string to split);

Ответ 3

хотя я тоже как-то бросаю вызов, но на самом деле это не одно. прочитайте эту статью http://secretgeek.net/csv_trouble.asp и затем продолжайте использовать http://www.filehelpers.com/

[Edit1, 3]: или, может быть, эта статья тоже может помочь (ссылка только показывает некоторый пример кода VB.Net, но все же вы можете использовать ее с С# тоже!): http://msdn.microsoft.com/en-us/library/cakac7e6.aspx

Я попытался сделать образец для С# (добавьте ссылку на Microsoft.VisualBasic в свой проект)

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]: нашел еще один, который мог бы помочь здесь: http://www.codeproject.com/KB/database/CsvReader.aspx

- reinhard

Ответ 4

... или вы могли установить пакет NuGet LumenWorks CsvReader и сделали что-то вроде ниже, где я прочитал файл csv, который имеет контент, например, например

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

и обрабатывать его следующим образом

public static void ProcessCsv()
        {
            var filename = @"your_file_path\filename.csv";
            DataTable dt = new DataTable("MyTable");

            List<string> product_codes = new List<string>();
            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);
                }
            }
        }

Ответ 5

Попробуйте (взломали Jens) в методе split:

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

или просто добавьте вопросительные знаки после Jens '*, это делает его ленивым, а не жадным.

Ответ 6

10021,9717398098, Администрация ULB, UnitedLex BPO Private Limited, Совлокальные услуги, DLF Building № 6, "Башня A, 1-й этаж, W-Block, DLF Phase-III", Гургаон, IN, Gurgaon Tower A Office, 122002, старший Управляющий, АДМИНИСТРАТИВНЫЕ И СРЕДСТВА, Упасана, upasana.sabharwal @unitedlex.com, Сабхарвал, НЕАКТИВНО, 5/1/2007,2/12/2015

Я не могу обработать эту строку с помощью выражения Regex, мне нужно избегать этих запятых в двойных кавычках. "Башня А, 1-й этаж, W-блок, DLF Фаза-III"

Ответ 7

Принятый ответ не работает для меня (можете вставить и протестировать в Regexr dot com и посмотреть, что не работает). Поэтому пришлось читать строки и массив строк, затем использовать (С#) Regex.Matches, чтобы получить массив любых строк между кавычками, а затем заменить запятые на || перед разделением каждого ряда. После разделения каждого ряда я вернулся, чтобы заменить || с запятыми.

        private static IEnumerable<string[]> ReadCsv(string fileName, char delimiter = ';')
    {
        string[] lines = File.ReadAllLines(fileName, Encoding.ASCII);
        // Before splitting on comma for a field array, we have to replace commas witin the fields
        for(int l = 1; l < lines.Length; l++)
        {
            //(\\")(.*?)(\\")
            MatchCollection regexGroup2 = Regex.Matches(lines[l], "(\\\")(.*?)(\\\")");
            if (regexGroup2.Count > 0)
            {
                for (int g = 0; g < regexGroup2.Count; g++)
                {
                    lines[l] = lines[l].Replace(regexGroup2[g].Value, regexGroup2[g].Value.Replace(",", "||"));
                }
            }
        }

        // Split
        IEnumerable<string[]> lines_split = lines.Select(a => a.Split(delimiter));

        // Reapply commas
        foreach(string[] row in lines_split)
        {
            for(int c = 0; c < row.Length; c++)
            {
                row[c] = row[c].Replace("||", ",");
            }
        }

        return (lines_split);
    }