简体   繁体   English

C#正则表达式中的贪婪,非贪婪,全贪婪匹配

[英]Greedy, Non-Greedy, All-Greedy Matching in C# Regex

How can I get all the matches in the following example: 在以下示例中,如何获取所有匹配项:

// 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"

PS: I want to have the all matches in a generic manner. PS:我想以一种通用的方式获得所有比赛。 The example above is just an example. 上面的例子只是一个例子。

You could use something like: 您可以使用类似:

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

Then you should have three backreferences with ab, abc and abcd. 然后,您应该使用ab,abc和abcd三个反向引用。

But, to be honest, this kind of regex doesn't makes too much sense, especially when it gets bigger it becomes unreadable. 但是,老实说,这种正则表达式没有太大意义,尤其是当它变大时,就变得不可读。

Edit: 编辑:

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

And you got an error there btw. 而且您在那里出现了一个错误。 This can only match ab and abc (read: ab + any (optional) character 这只能匹配ab和abc(读取:ab +任何(可选)字符)

Lazy version of: 惰性版本:

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

is: 是:

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

If a solution exists, it probably involves a capturing group and the RightToLeft option: 如果存在解决方案,则可能涉及捕获组和RightToLeft选项:

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

output: 输出:

abcd
abc
ab

I say "if" because, while it works for your simple test case, I can't guarantee this trick will help with your real-world problem. 我说“ if”是因为,尽管它适用于您的简单测试用例,但我不能保证此技巧将有助于解决您的实际问题。 RightToLeft mode is one of .NET's more innovative features--offhand, I can't think of another flavor that has anything equivalent to it. RightToLeft模式是.NET更具创新性的功能之一-顺便说一句,我想不出具有与之等效的其他功能。 The official documentation on it is sparse (to put it mildly), and so far there don't seem to be a lot developers using it and sharing their experiences online. 关于它的官方文档很少(稍微说一下),到目前为止,似乎没有多少开发人员使用它并在线共享他们的经验。 So try it and see what happens. 因此,尝试一下,看看会发生什么。

You can't get three different results from only one match. 您只能从一场比赛中获得三种不同的结果。

If you want to match only "ab" you can use ab.? 如果只想匹配“ ab”,则可以使用ab.? or a.{1} (or a lot of other options) a.{1} (或许多其他选项)
If you want to match only "abc" you can use ab. 如果只想匹配“ abc”,则可以使用ab. or a.{2} (or a lot of other options) a.{2} (或许多其他选项)
If you want to match only "abcd" you can use ab.* or a.{3} (or a lot of other options) 如果只想匹配“ abcd”,则可以使用ab.*a.{3} (或许多其他选项)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM