在C#中计算与Regex的重叠匹配

时间:2012-08-13 22:10:00

标签: c# regex

以下代码评估2而不是4:

Regex.Matches("020202020", "020").Count;

我猜测正则表达式从上一场比赛结束开始寻找下一场比赛。有什么办法可以防止这种情况发生。我有一串'0'和'2',我试着计算连续三次'2'连续多少次,连续四次'2'等等。

5 个答案:

答案 0 :(得分:9)

这将按预期返回4

Regex.Matches("020202020", @"0(?=20)").Count;

前瞻匹配 20而没有消费它,所以下一次匹配尝试从第一个0之后的位置开始。您甚至可以将整个正则表达式作为前瞻:

Regex.Matches("020202020", @"(?=020)").Count;

每次进行零长度匹配时,正则表达式引擎会自动向前移动一个位置。因此,要查找三个2或四个2的所有运行,您可以使用:

Regex.Matches("22222222", @"(?=222)").Count;  // 6

...和

Regex.Matches("22222222", @"(?=2222)").Count;  // 5

编辑:再次查看您的问题,我可能会想到2穿插0

Regex.Matches("020202020", @"(?=20202)").Count;  // 2

如果你不知道会有多少0,你可以使用它:

Regex.Matches("020202020", @"(?=20*20*2)").Count;  // 2

当然,您可以使用量词来减少正则表达式中的重复:

Regex.Matches("020202020", @"(?=2(?:0*2){2})").Count;  // 2

答案 1 :(得分:4)

实际上,正则表达式将从最后一个结束的地方继续。您可以使用先行模式解决它。我不是.NET的人,但试试这个:"(?=020)."翻译:“找到任何一个字符,这个字符和接下来的两个字符是020”。诀窍是匹配只有一个字符宽,而不是三个,所以你将获得字符串中的所有匹配,即使它们重叠。

(你也可以把它写成"0(?=20)",但至少人类不太清楚:p)

答案 2 :(得分:1)

尝试使用零宽度正向后观:

Regex.Matches("020202020",@"(?<=020)").Count;

为我工作,收获4场比赛。

我最喜欢的正则表达式参考:Regular Expression Language - Quick Reference 也是尝试使用Regex的快速方法,我经常使用它来处理复杂的正则表达式:Free Regular Expression Designer

答案 3 :(得分:0)

假设您确实在寻找连续2 - s的序列,还有另一个选项,而不使用任何前瞻。 (这对于查找02模式的任意序列不起作用。)

枚举所有出现的三个或更多2 - s的非重叠序列(如何?),然后推断出较短子序列的数量。

例如,如果您找到一个连续六个2 - s和五个连续2 - s之一的序列,那么您知道必须有(6-3 + 1)+( 5-3 + 1)=?连续三个2 - s(可能重叠)的序列,依此类推:

0002222220000002222200
   222
    222
     222
      222
               222
                222
                 222

对于大字符串,这应该比使用前瞻稍微更快

答案 4 :(得分:-4)

因为来源包含两个&#34; 020&#34;你的正则表达式模式匹配的模式。尝试将您的来源更改为:

Regex.Matches("020202020", "02").Count;

现在它将连续匹配02,这次你将得到4个。