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

Эффективно сочетать MatchCollections в .Net Regex

В упрощенном примере есть 2 регулярных выражения, один регистр чувствителен, другой нет. Идея состоит в том, чтобы эффективно создать коллекцию IEnumerable (см. Ниже "комбинированное" ), объединяющее результаты.

string test = "abcABC";
string regex = "(?<grpa>a)|(?<grpb>b)|(?<grpc>c)]";
Regex regNoCase = new Regex(regex, RegexOptions.IgnoreCase);
Regex regCase = new Regex(regex);

MatchCollection matchNoCase = regNoCase.Matches(test);
MatchCollection matchCase = regCase.Matches(test);

//Combine matchNoCase and matchCase into an IEnumerable
IEnumerable<Match> combined= null;
foreach (Match match in combined)
{
    //Use the Index and (successful) Groups properties 
    //of the match in another operation

}

На практике MatchCollections может содержать тысячи результатов и часто запускаться с использованием длинных динамически создаваемых REGEX, поэтому я хотел бы уклониться от копирования результатов в массивы и т.д. Я все еще изучаю LINQ и не знаю, как чтобы объединить эти или то, что производительность попадает на уже вялый процесс.

4b9b3361

Ответ 1

Здесь есть три шага:

  • Преобразуйте MatchCollection в IEnumerable<Match>
  • Объединить последовательности
  • Отфильтровать, верно ли свойство Match.Success

код:

IEnumerable<Match> combined = matchNoCase.OfType<Match>().Concat(matchCase.OfType<Match>()).Where(m => m.Success);

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

Ответ 2

Ответ, помеченный правильно, создает IEnumerable с двумя из каждого соответствия. Правильный способ объединения приведен ниже:

var combined = matches.Where(e=>e.Success).Select(e=>e.Value);