C# 正则表达式中的重叠匹配

C# 正则表达式中的重叠匹配,c#,regex,overlap,C#,Regex,Overlap,我似乎找不到这个问题的答案,我想知道是否有答案。简化示例: 考虑一个字符串“nnnn”,我想在其中查找“nn”的所有匹配项,但也要查找彼此重叠的匹配项。因此,正则表达式将提供以下3个匹配项: nnnn nnnn nnnn 我意识到这并不完全是正则表达式的目的,但是遍历字符串并手动解析它看起来像是一大堆代码,考虑到在现实中,匹配必须使用模式而不是文字字符串来完成。好吧,没有一种纯粹的正则表达式方法可以立即做到这一点(即,返回您请求的三个捕获,无需循环) 现在,您可以一次找到一个模式,然后从offs

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

考虑一个字符串“nnnn”,我想在其中查找“nn”的所有匹配项,但也要查找彼此重叠的匹配项。因此,正则表达式将提供以下3个匹配项:

  • nnnn
  • nnnn
  • nnnn

  • 我意识到这并不完全是正则表达式的目的,但是遍历字符串并手动解析它看起来像是一大堆代码,考虑到在现实中,匹配必须使用模式而不是文字字符串来完成。

    好吧,没有一种纯粹的正则表达式方法可以立即做到这一点(即,返回您请求的三个捕获,无需循环)

    现在,您可以一次找到一个模式,然后从offset(find position+1)开始循环搜索。应该将regex用法与简单代码结合使用

    [编辑]太好了,当我基本上说出简所展示的内容时,我被否决了…

    [编辑2]澄清一下:简的答案更好。不是更精确,但肯定更详细,值得选择。我只是不明白为什么我的答案被否决,因为我仍然没有看到任何错误。没什么大不了的,只是很烦人。

    一个可能的解决方案是使用:

    这将引用所需字符串的第一个位置,并捕获组(2)中的第二个n

    这是因为:

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

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

    使用带有捕获组的前瞻功能,代价是使正则表达式更慢、更复杂。另一种解决方案是告诉regex.Match()方法下一次匹配尝试应该从何处开始。请尝试以下方法:

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

    比我快1秒钟,我会收回我相同的答案!@Timothy:那不会捕获,你还得循环结果,所以我不确定有什么好处…@PhiLho:再一次,不是真的:你可以用零宽度断言来捕获组,就像一个积极的展望。请看我的-完成-答案。@PhiLho:我回应了你的评论。还有,在我看来,你的回答不如简的准确:“模式”可以指“n”,而正确的策略意味着使用“nn”,然后在偏移量+1处重新开始。你的意思可能是,你一直没有解释它。@VonC:问题是准确的,模式是“nn”一直以来,我看不出有什么模棱两可的地方。而且,你可以用积极的前瞻性来做:(?=nn)n…这表示“前方是两个n,匹配一个n”。对不起,但我仍然看不到要求的三个重叠捕获。你捕获两个n,但不是三个组。如果我匹配(\d\d)(?=(\d\d))针对foo4237bar,我得到了两个捕获,而不是三个:42和37(在Regex Coach和PCRE Workbench中)。我可能很胖,所以我需要更多的解释。请再次阅读答案:(\d)(?=(\d)),而不是(\d\d)(?=(\d\d)):您将有三组捕获组:(4)(2),(2)(3),(7)为什么不只是
    (?=(nn))
    ?然后您可以为每个匹配Regular-Expressions.info网站管理员获得一个捕获组…=>必填+1。另外,您当然是对的。
    (n)(?=(n))
    
    Regex regexObj = new Regex("nn");
    Match matchObj = regexObj.Match(subjectString);
    while (matchObj.Success) {
        matchObj = regexObj.Match(subjectString, matchObj.Index + 1); 
    }