it-swarm.com.ru

Жадный, не жадный, всесожжение в 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"

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

21
Peter Lee

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

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

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

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

Правка:

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

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

Ленивая версия:

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

является:

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

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

4
Alan Moore

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

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

1
Colin Hebert