Жадность, Нежелательное, Всепоглощающее соответствие в С# 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.: Я хочу, чтобы все совпадения носили общий характер. Пример, приведенный выше, является лишь примером.
Ответы
Ответ 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}
(или множество других опций)