Как Regex.Split дает мне совпадающие матчи? - PullRequest
0 голосов
/ 18 декабря 2010

У меня есть большое регулярное выражение, которое я использую для анализа моего собственного формата файла, похожего на lua. Это работает нормально, за исключением того, что числа внутри кавычек совпадают дважды, даже если split не должен возвращать перекрывающиеся результаты. Я упростил это до этого консольного приложения. Есть идеи?

static void Main(string[] args)
{
    string pattern = "(\r\n)|(\"(.*)\")"; // Splits at \r\n and anything in "quotes"

    string input = "\"01\"\r\n" + // "01"
                   "\"02\"\r\n" + // "02"
                   "\"03\"\r\n";  // "03"

    string[] results = Regex.Split(input, pattern );
    foreach (string result in results )
    {
            //This just filters out the split \r\n and empty strings in results
            if (string.IsNullOrWhiteSpace(result) == false) 
                Console.WriteLine(result);
    }
    Console.ReadLine();
}

Возвращает:

"01"
01
"02"
02
"03"
03

Ответы [ 2 ]

2 голосов
/ 18 декабря 2010

Из документации :

Если в выражении Regex.Split используются захватывающие скобки, любой полученный текст включается в результирующий массив строк. Например, разделение строки «сливовая груша» на дефис, помещенный в скобки для ввода, добавляет строковый элемент, содержащий дефис к возвращаемому массиву.

У вас есть два набора захватывающих скобок, один с кавычками и один с исключительными. Они возвращают строки, которые вы видите.

Обратите внимание, что шаблон для RegEx.Split не должен соответствовать желаемым результатам, он должен соответствовать разделителям. Строка в кавычках обычно не является разделителем.

Кроме того, ваши результаты кажутся очень странными, потому что вы использовали жадный матч. Видимо, требование «входная строка разбивается столько раз, сколько возможно». делает сопоставление нежадным для всей операции.

В целом, я бы сказал, что вы используете не тот инструмент. Регулярные выражения, в зависимости от реализации, не способны работать с вложенными группировками или крайне неэффективны. Простой DFA должен работать намного лучше и никогда не требует больше, чем одно сканирование.

1 голос
/ 18 декабря 2010

просто удалите внешние скобки,

string pattern = "(\r\n)|\"(.*)\"";

//Tested output:
01
02
03
...