Жадный, не-жадный, все-жадный соответствия в C# 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.: Я хочу, чтобы все матчи в обобщенном виде. Приведенный выше пример-всего лишь пример.

3 ответов


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

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

тогда у вас должно быть три backreferences с ab, abc и abcd.

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

Edit:

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

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

ленивая версия из:

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

- это:

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

Если решение существует, оно, вероятно, включает в себя группу захвата и параметр 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 mode-одна из более инновационных функций .NET-навскидку, я не могу придумать другого аромата, который имеет что-то эквивалентное ему. Официальная документация на него разрежена (мягко говоря), и так далеко не кажется, что разработчики используют его и делятся своим опытом в интернете. Попробуй и увидишь, что получится.


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

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