繁体   English   中英

正则表达式中的重叠匹配

[英]Overlapping matches in Regex

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

考虑一个字符串“nnnn”,我想在其中找到“nn”的所有匹配项——但也包括那些相互重叠的匹配项。 因此,正则表达式将提供以下 3 个匹配项:

  1. 嗯嗯
  2. n n n
  3. 嗯嗯

我意识到这并不完全是正则表达式的含义,但是手动遍历字符串并解析它似乎是很多代码,考虑到实际上必须使用模式而不是文字字符串来完成匹配。

2016 年更新:

要获得nnnnnnSDJMcHattie评论中建议(?=(nn)) (参见 regex101)

(?=(nn))

原始答案(2008)

一个可能的解决方案可能是使用正面的看法

(?<=n)n

它会给你的最终位置:

  1. n n n
  2. n n n n
  3. n n n

正如Timothy Khouri所提到的,积极的前瞻更直观(参见示例

我更喜欢他的命题(?=nn)n更简单的形式:

(n)(?=(n))

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

之所以如此,是因为:

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

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


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

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

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

现在,您可以找到一次模式,然后从偏移量(找到的位置 + 1)开始循环搜索。 应该将正则表达式的使用与简单的代码结合起来。

[编辑] 太好了,当我基本上说出 Jan 所展示的内容时,我被否决了……
[编辑 2] 要明确:简的答案更好。 不是更精确,但肯定更详细,值得选择。 我只是不明白为什么我的投票被否决了,因为我仍然没有看到任何不正确的地方。 没什么大不了的,就是烦。

暂无
暂无

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

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