C#Regex中的贪婪,非贪婪,全贪婪的匹配

Pet*_*Lee 21 c# regex greedy non-greedy regex-greedy

如何在以下示例中获取所有匹配项:

// 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"
Run Code Online (Sandbox Code Playgroud)

PS:我希望以通用方式获得所有比赛.上面的例子只是一个例子.

Tse*_*eng 19

你可以使用类似的东西:

MatchCollection nonGreedyMatches = Regex.Matches("abcd", @"(((ab)c)d)");
Run Code Online (Sandbox Code Playgroud)

然后你应该有ab,abc和abcd的三个反向引用.

但是,说实话,这种正则表达式并没有多大意义,特别是当它变大时变得难以理解.

编辑:

MatchCollection nonGreedyMatches = Regex.Matches("abcd", @"ab.?");
Run Code Online (Sandbox Code Playgroud)

你有一个错误.这只能匹配ab和abc(读取:ab +任意(可选)字符

懒人版:

MatchCollection greedyMatches    = Regex.Matches("abcd", @"ab.*");
Run Code Online (Sandbox Code Playgroud)

是:

MatchCollection nonGreedyMatches    = Regex.Matches("abcd", @"ab.*?");
Run Code Online (Sandbox Code Playgroud)


Ala*_*ore 6

如果存在解决方案,它可能涉及捕获组和 RightToLeft 选项:

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

输出:

abcd
abc
ab
Run Code Online (Sandbox Code Playgroud)

我说“如果”是因为,虽然它适用于您的简单测试用例,但我不能保证这个技巧会帮助您解决实际问题。 RightToLeft模式是 .NET 更具创新性的特性之一——随手,我想不出另一种风格可以与它相提并论。关于它的官方文档很少(说得客气一点),到目前为止似乎没有多少开发人员使用它并在线分享他们的经验。所以尝试一下,看看会发生什么。