正则表达式查找所有重叠的匹配项

时间:2019-10-01 16:00:36

标签: php regex string search

试图找到所有可能的数字匹配,用空格分隔。 已经尝试先行和后行构建,但这无济于事。

我们有一个由数字组成的字符串(0..99)。

我们需要找到所有长度大于3且可能包含特殊符号(例如“ 1”)的数字序列。

符号“ 1”是通用符号,可以替换任何数字。例如,“ 2 2 2 2”,“ 1 2 1 2”,“ 2 1 2 2”,“ 2 2 2 1”是有效的匹配项。

一切正常,除了这种情况,两个匹配项拥有符号“ 1”:

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

原始字符串:

3 1 1 4 4 4 4 1 4 4 5 5 1 5 5 6 7 8 1 9 9 9 9 9 9 1 3 4 5 5 1 1 5 5 6 4 4 4 1 7 1 2 2 2 2 2 2 2 1 11 11 11 11 

除了最后一场比赛,我的正则表达式几乎一切正常:

/(1 ){0,}(\d |\d\d )\2{1,}(1 ){0,}\2{1,}(1 ){0,}/g

当前结果(请参阅最后一场比赛,其必须为“ 1 11 11 11 11 11”):

1 1 4 4 4 4 1 4 4 
5 5 1 5 5 
1 9 9 9 9 9 9 1 
5 5 1 1 5 5 
4 4 4 1 
1 2 2 2 2 2 2 2 1 
11 11 11 11 

目标:

1 1 4 4 4 4 1 4 4 
5 5 1 5 5 
1 9 9 9 9 9 9 1 
5 5 1 1 5 5 
4 4 4 1 
1 2 2 2 2 2 2 2 1 
1 11 11 11 11 

正则表达式/(?=((1 ){0,}(\d |\d\d )\3{1,}(1 ){0,}\3{1,}(1 ){0,}))/g给重叠带来了很多变化。

此处沙箱:https://regex101.com/r/VDa6LZ/2

如何正确找到所有重叠的匹配项?

1 个答案:

答案 0 :(得分:0)

似乎找到了solution proposed by @bobblebubble。不太简单,但是可以解决问题。

\b(?|(?=(((?:1 )+(\d?\d )\3+(?:1 )*\3+)(?:1 )*))\2|((\d?\d )\2+(?:1 )*\2+(?:1 )*))

结果将在第1组

  • (?|通过使用branch reset,管道两边的外部组将被捕获为组1。
  • (?=(((?:1 )+(\d?\d )\3+(?:1 )*\3+)(?:1 )*))\2的左侧是用于捕获超前区域内重叠的1部分。第2组仅用于消耗零件,直到1的最后一次出现开始,因为我们不希望所有子序列出现。
  • ((\d?\d )\2+(?:1 )*\2+(?:1 )*)的右侧用于捕获其余序列。