Как я могу исправить это выражение регулярного выражения?

Предисловие: Этот вопрос является производным от этого вопроса .


Вот мой код :

using System;
using System.Linq;
using System.Text.RegularExpressions;

class MainClass {
  public static void Main (string[] args) {
        const string rawLine = ""TeamName","PlayerName","Position"  "Chargers","Philip Rivers","QB"  "Colts","Peyton Manning","QB"  "Patriots","Tom Brady","QB"";
        var parsedLines = Regex.Split(rawLine, "(".*? "(?:,".*? ")*)");
        parsedLines.ToList().ForEach(Console.WriteLine);

        Console.WriteLine("Press [ENTER] to exit.");
        Console.ReadLine();
  }
}

Вот мой вывод:

"TeamName","PlayerName","Position"  "
Chargers
","Philip Rivers","QB"  "
Colts
","Peyton Manning","QB"  "
Patriots","Tom Brady","QB"
Press [ENTER] to exit.

И вот мой желаемый результат:

"TeamName","PlayerName","Position"
"Chargers","Philip Rivers","QB"
"Colts","Peyton Manning","QB"
"Patriots","Tom Brady","QB"
Press [ENTER] to exit.

Как я могу исправить регулярное выражение для создания желаемого результата?

Всего 3 ответа


Как уже говорила Эми, ваша строка выглядит как CSV. Если это действительно действующий CSV - используйте специальные библиотеки.

Если CSVHelper не применим в этом случае, и вам действительно нужно регулярное выражение, попробуйте что-то вроде этого:

(?<=(?:^|  ))(.*?)(?=(?:  ")|$)

Я не программировал для C #, поэтому регулярное выражение может нуждаться в некоторых изменениях из-за специфики C #.

Редактировать. Пример кода.

using System;
using System.Linq;
using System.Text.RegularExpressions;

class MainClass {
  public static void Main (string[] args) {
        const string rawLine = ""TeamName","PlayerName","Position"  "Chargers","Philip Rivers","QB"  "Colts","Peyton Manning","QB"  "Patriots","Tom Brady","QB"";
            //var parsedLines = Regex.Split(rawLine, "(?<=(?:^|  ))(.*?)(?=(?:  ")|$)");
      var parsedLines = Regex.Split(rawLine, "(?<=^)(.*?)(?=(?:  ")|$)|(?<=  )(.*?)(?=(?:  ")|$)");
            parsedLines.ToList().ForEach(Console.WriteLine);

            Console.WriteLine("Press [ENTER] to exit.");
            Console.ReadLine();
  }
}

Этот код с «грязным» исправлением для ошибки утверждения. Тем не менее, я не могу воспроизвести его с помощью onlinetool :) Оригинальное регулярное выражение прокомментировано в этом примере.

Я надеюсь, что это поможет вам. Но я должен сказать еще раз, если вы работаете с CSV - лучше использовать специальные инструменты, а не регулярное выражение :)


Хорошие комментарии по всей ветке (я настоятельно рекомендую использовать один из этих вариантов), я не буду на них останавливаться. Вот альтернативное решение, которое использует Matches из шаблона Regex , skip сколько у вас полей (столбцов), а затем take сколько записей вы хотите.

Я использую шаблон как ("(.*?)[^,]") И здесь можно найти объяснение, что это значит.

const string rawLine = ""TeamName","PlayerName","Position"  "Chargers","Philip Rivers","QB"  "Colts","Peyton Manning","QB"  "Patriots","Tom Brady","QB"";                       
var matches = new Regex(@"(""(.*?)[^,]"")").Matches(rawLine).Cast<Match>().ToList();
// loop through our matches
for(int i = 0; i < matches.Count; i++)
{                
    // join our records we need to output
    string str = string.Join(",", matches.Skip(i * 3).Take(3));
    if(!string.IsNullOrEmpty(str))
         Console.WriteLine(str);
}            
Console.WriteLine("Press [ENTER] to exit.");
Console.ReadLine();

Обратите внимание, что нет никакой проверки ошибок, она может быть улучшена, но выдает нужный результат. * Также убедитесь, что вы импортируете System.Linq если его там еще нет.

Тест выхода

введите описание изображения здесь


Используйте отрицательный взгляд назад, положительный взгляд назад, класс символов с квантифером, положительный взгляд и отрицательный взгляд.

Рабочая Демо

using System;
using System.Linq;
using System.Text.RegularExpressions;

class MainClass {
  public static void Main (string[] args) {
        const string rawLine = ""TeamName","PlayerName","Position"  "Chargers","Philip Rivers","QB"  "Colts","Peyton Manning","QB"  "Patriots","Tom Brady","QB"";
            var parsedLines = Regex.Split(rawLine, "(?<![,])(?<=["])[ ]{2}(?=["])(?![,])");
            parsedLines.ToList().ForEach(Console.WriteLine);

            Console.WriteLine("Press [ENTER] to exit.");
            Console.ReadLine();
  }
}

Есть идеи?

10000