在Regex中重叠匹配

时间:2008-11-26 11:50:44

标签: c# regex overlap

我似乎无法找到这个问题的答案,我想知道是否存在。简化示例:

考虑一个字符串“nnnn”,我想找到“nn”的所有匹配 - 但也是那些彼此重叠的匹配。因此正则表达式将提供以下3个匹配:

  1. NN
  2. 名词名词
  3. ン的
  4. 我意识到这并不是正则表达式的意思,但是对字符串进行操作并手动解析它似乎是一个非常多的代码,考虑到实际上匹配必须使用模式而不是文字字符串来完成

3 个答案:

答案 0 :(得分:25)

使用带有捕获组的前瞻工作,代价是使正则表达式更慢,更复杂。另一种解决方案是告诉Regex.Match()方法,下一次匹配尝试应该从哪里开始。试试这个:

Regex regexObj = new Regex("nn");
Match matchObj = regexObj.Match(subjectString);
while (matchObj.Success) {
    matchObj = regexObj.Match(subjectString, matchObj.Index + 1); 
}

答案 1 :(得分:20)

可能的解决方案是使用positive look behind

(?<=n)n

它会给你最终位置:

  1. * N *** **Ñン
  2. N×N个***Ñ** N
  3. ン* N *** **Ñ

  4. 正如Timothy Khouri所提到的,正向前瞻更直观

    我更希望他的命题(?=nn)n更简单:

    (n)(?=(n))
    

    这将引用您想要的字符串的第一个位置,并将捕获组(2)中的第二个

    那是因为:

    • 可以在前瞻中使用任何有效的正则表达式。
    • 如果它包含捕获括号,则反向引用将被保存

    因此,组(1)和组(2)将捕获'n'代表的任何内容(即使它是一个复杂的正则表达式)。

答案 2 :(得分:1)

AFAIK,没有纯正的正则表达方法可以立即执行此操作(即返回您请求的三个捕获而不循环)。

现在,您可以找到一次模式,并以offset(找到位置+ 1)开始循环搜索。应该将正则表达式与简单代码结合使用。

[编辑]太棒了,当我基本上说Jan所示的时候,我被投票了 [编辑2]要明确:Jan的答案更好。不是更精确,但肯定更详细,值得选择。我只是不明白为什么我的被投票,因为我仍然没有看到任何错误。没什么大不了的,只是讨厌。