Регулярное выражение для разделения на запятую, если не указано - PullRequest
6 голосов
/ 11 ноября 2010

Какое регулярное выражение разделяется на запятую (,), если оно не заключено в двойные кавычки?Например:

max,emily,john = ["max", "emily", "john"]

НО

max,"emily,kate",john = ["max", "emily,kate", "john"]

Хотите использовать в C #: Regex.Split(string, "PATTERN-HERE");

Спасибо.

Ответы [ 4 ]

14 голосов
/ 11 ноября 2010

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

Вместо этого вы можете попробовать что-то вроде этого:

public static IEnumerable<string> SplitCSV(string csvString)
{
    var sb = new StringBuilder();
    bool quoted = false;

    foreach (char c in csvString) {
        if (quoted) {
            if (c == '"')
                quoted = false;
            else
                sb.Append(c);
        } else {
            if (c == '"') {
                quoted = true;
            } else if (c == ',') {
                yield return sb.ToString();
                sb.Length = 0;
            } else {
                sb.Append(c);
            }
        }
    }

    if (quoted)
        throw new ArgumentException("csvString", "Unterminated quotation mark.");

    yield return sb.ToString();
}

Вероятно, потребуется несколько настроек дляточно следуйте спецификации CSV, но основная логика - это звук.

1 голос
/ 11 ноября 2010

Это очевидный случай для анализатора CSV, поэтому вы должны использовать собственные возможности синтаксического анализа CSV .NET или решение cdhowie.

Чисто для вашей информации, а , а не , предназначенный в качестве работоспособного решения, вот то, что вы должны пройти, используя регулярные выражения с Regex.Split():

Вы можете использовать регулярное выражение (, пожалуйста, не надо! )

(?<=^(?:[^"]*"[^"]*")*[^"]*)  # assert that there is an even number of quotes before...
\s*,\s*                       # the comma to be split on...
(?=(?:[^"]*"[^"]*")*[^"]*$)   # as well as after the comma.

если ваши строки в кавычках никогда не содержат экранированных кавычек, и вы не против того, чтобы сами цитаты становились частью матча.

Это ужасно неэффективно, боль в чтении и отладке, работает только в .NET, и не работает на экранированных кавычках (по крайней мере, если вы не используете "" для экранирования одиночной кавычки). Конечно, регулярное выражение можно изменить, чтобы справиться и с этим, но тогда это будет совершенно ужасно.

0 голосов
/ 27 мая 2014

Джастин, воскрешает этот вопрос, потому что у него было простое решение регулярных выражений, которое не было упомянуто. Эта ситуация звучит прямо из Соответствует (или заменяет) паттерн, за исключением ситуаций s1, s2, s3 и т. Д. .

Вот наше простое регулярное выражение:

"[^"]*"|(,)

Левая сторона чередования соответствует полному тегу "quoted strings". Мы будем игнорировать эти матчи. Правая сторона сопоставляет и вводит запятые в Группу 1, и мы знаем, что они являются правыми запятыми, поскольку они не совпадают с выражением слева. Мы заменим эти запятые на SplitHere, затем разделим на SplitHere.

Эта программа показывает, как использовать регулярные выражения (см. Результаты в нижней части онлайн-демонстрации ):

using System;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
class Program
{
static void Main()  {
string s1 = @"max,""emily,kate"",john";
var myRegex = new Regex(@"""[^""]*""|(,)");
string replaced = myRegex.Replace(s1, delegate(Match m) {
    if (m.Groups[1].Value == "") return m.Value;
    else return "SplitHere";
    });
string[] splits = Regex.Split(replaced,"SplitHere");
foreach (string split in splits) Console.WriteLine(split);
Console.WriteLine("\nPress Any Key to Exit.");
Console.ReadKey();
} // END Main
} // END Program

Ссылка

Как сопоставить (или заменить) шаблон, кроме случаев s1, s2, s3 ...

0 голосов
/ 26 июля 2012

Возможно, немного поздно, но я надеюсь, что смогу помочь кому-то еще

     String[] cols = Regex.Split("max, emily, john", @"\s*,\s*");
     foreach ( String s in cols ) {
        Console.WriteLine(s);
     }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...