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

Жадность, Нежелательное, Всепоглощающее соответствие в С# Regex

Как получить все совпадения в следующем примере:

// Only "abcd" is matched
MatchCollection greedyMatches = Regex.Matches("abcd", @"ab.*");

// Only "ab" is matched
MatchCollection lazyMatches   = Regex.Matches("abcd", @"ab.*?");

// How can I get all matches: "ab", "abc", "abcd"

P.S.: Я хочу, чтобы все совпадения носили общий характер. Пример, приведенный выше, является лишь примером.

4b9b3361

Ответ 1

Вы можете использовать что-то вроде:

MatchCollection nonGreedyMatches = Regex.Matches("abcd", @"(((ab)c)d)");

Затем у вас должно быть три обратных ссылки с ab, abc и abcd.

Но, если честно, такое регулярное выражение не имеет особого смысла, особенно когда оно становится больше, оно становится нечитаемым.

Edit:

MatchCollection nonGreedyMatches = Regex.Matches("abcd", @"ab.?");

И вы получили там ошибку. Это может соответствовать только ab и abc (читайте: ab + any (необязательный) символ

Lazy версия:

MatchCollection greedyMatches    = Regex.Matches("abcd", @"ab.*");

является:

MatchCollection nonGreedyMatches    = Regex.Matches("abcd", @"ab.*?");

Ответ 2

Если решение существует, вероятно, оно включает в себя группу захвата и параметр RightToLeft:

string s = @"abcd";
Regex r = new Regex(@"(?<=^(ab.*)).*?", RegexOptions.RightToLeft);
foreach (Match m in r.Matches(s))
{
  Console.WriteLine(m.Groups[1].Value);
}

выход:

abcd
abc
ab

Я говорю "если", потому что, хотя он работает для вашего простого теста, я не могу гарантировать, что этот трюк поможет в решении вашей реальной проблемы. RightToLeft режим является одним из .NET более инновационных функций - небрежно, я не могу думать о другом вкусе, который имеет что-то эквивалентное ему. Официальная документация на нее разрежена (мягко говоря), и пока не так много разработчиков, использующих ее и делясь своим опытом в Интернете. Поэтому попробуйте и посмотрите, что произойдет.

Ответ 3

Вы не можете получить три разных результата только из одного соответствия.

Если вы хотите совместить только "ab", вы можете использовать ab.? или a.{1} (или множество других опций)
Если вы хотите совместить только "abc", вы можете использовать ab. или a.{2} (или множество других опций)
Если вы хотите совместить только "abcd", вы можете использовать ab.* или a.{3} (или множество других опций)