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

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

  1. nn

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

有帮助吗?

解决方案

一个可能的解决方案是使用 积极向后看:

(?<=n)n

它会给你的最终位置:

  1. *n***n**nn
  2. n*n***n**n
  3. nn*n***n**

正如所提到的 蒂莫西·库里, , A 积极的前瞻 更直观

我更愿意接受他的提议 (?=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)开始循环搜索。应该将正则表达式的使用与简单的代码结合起来。

[编辑] 太好了,当我基本上说出简所展示的内容时,我被否决了......
[编辑2] 需要明确的是:简的回答更好。不是更精确,但肯定更详细,值得选择。我只是不明白为什么我的被否决了,因为我仍然认为它没有任何不正确的地方。没什么大不了的,只是烦人而已。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top