Как я могу исправить это выражение регулярного выражения? - PullRequest
0 голосов
/ 16 января 2020

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


Вот мой код :

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 ]

1 голос
/ 17 января 2020

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

Рабочая демонстрация

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();
  }
}
0 голосов
/ 16 января 2020

Хорошие комментарии по всей теме (я настоятельно рекомендую использовать один из этих вариантов), я не буду на них фокусироваться. Вот альтернативное решение, которое использует 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, если его там еще нет.

Проверка вывода

enter image description here

0 голосов
/ 16 января 2020

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

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

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

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

Edit. Пример кода.

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 - лучше использовать специальные инструменты, а не регулярное выражение:)

...