Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php RegExp。查找所有重叠的匹配项_Php_Regex_String_Search - Fatal编程技术网

Php RegExp。查找所有重叠的匹配项

Php RegExp。查找所有重叠的匹配项,php,regex,string,search,Php,Regex,String,Search,正在尝试查找由空格分隔的数字的所有可能匹配项。 已经在尝试使用“向前看”和“向后看”进行构建,但没有任何帮助 我们有一串分隔的数字(0..99) 我们需要找到所有长度大于3且可能包含特殊符号的数字序列,例如“1” 符号“1”是通用符号,可以替换任何数字。例如,“2 2 2 2”,“1 2 1 2”,“2 1 2”,“2 2 2 1”是有效的匹配项 除符号“1”由两个匹配项拥有的情况外,一切正常: ... 2 2 2 2 1 3 3 3 3 ... 原始字符串: 3 1 1 4 4 4 4 1

正在尝试查找由空格分隔的数字的所有可能匹配项。 已经在尝试使用“向前看”和“向后看”进行构建,但没有任何帮助

我们有一串分隔的数字(0..99)

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

符号“1”是通用符号,可以替换任何数字。例如,“2 2 2 2”,“1 2 1 2”,“2 1 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”):

目标:

Regexp
/(?=((1){0,}(\d |\d\d)\3{1,}(1){0,}\3{1,}(1){0,}))/g
给出了许多重叠变化

这里是沙盒:

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

似乎找到了。不太简单,但解决了问题

\b(?|(?=(((?:1 )+(\d?\d )\3+(?:1 )*\3+)(?:1 )*))\2|((\d?\d )\2+(?:1 )*\2+(?:1 )*))
结果将在第1组

  • (?|
    通过使用,管道两侧的外部组将被捕获为组1
  • (?=((?:1)+(\d?\d)\3+(?:1)*\3+(:1)*)\2
    交替的左侧用于捕获前瞻中重叠的
    1
    部分。第2组仅用于消费部分,直到
    1
    的最后一次出现开始,因为我们不需要所有子序列
  • ((\d?\d)\2+(?:1)*\2+(?:1)*)
    右侧用于捕获剩余序列
似乎找到了。不太简单,但解决了问题

\b(?|(?=(((?:1 )+(\d?\d )\3+(?:1 )*\3+)(?:1 )*))\2|((\d?\d )\2+(?:1 )*\2+(?:1 )*))
结果将在第1组

  • (?|
    通过使用,管道两侧的外部组将被捕获为组1
  • (?=((?:1)+(\d?\d)\3+(?:1)*\3+(:1)*)\2
    交替的左侧用于捕获前瞻中重叠的
    1
    部分。第2组仅用于消费部分,直到
    1
    的最后一次出现开始,因为我们不需要所有子序列
  • ((\d?\d)\2+(?:1)*\2+(?:1)*)
    右侧用于捕获剩余序列

问题是,第一个可选子模式和最后一个可选子模式是相同的。可能您可以使用类似正则表达式的
/(?:1)*(\d\d\d)\1+(1)*\1+(?=(1)*)/
当您使用
preg_match_all
获得结果时,检查第1组是否匹配,如果匹配,则将整个匹配与第1组值合并。使用lookaheads部分回答:
(?=(?:(?请注意-这将正确地允许重叠匹配,但将匹配比您的示例更多的有效序列。我提出了一个很难理解的方法,目前我没有时间解释。其想法是使用分支重置组在重叠
1
之间交替,但只消耗部分,直到最后一个
1
序列并捕获非重叠,无需前瞻。结果将在第1组中。谢谢大家!@bobblebubble您的解决方案
\b(?)(((?:1)+(\d?\d)\3+(?:1)*\3+(?:1)*)\2((\d?\d)\2+(?:1)*\2+(?:1)*)
太棒了!这就是我要找的!谢谢!!这能回答你的问题吗?问题是第一个可选子模式和最后一个可选子模式是相同的。也许你可以使用类似于
/(?:1)*(\d |\d\d)\1+(1)*\1+(?=(1)*)的正则表达式/
当您使用
preg_match_all
获得结果时,检查第1组是否匹配,如果匹配,则将整个匹配与第1组值合并。使用lookaheads部分回答:
(?=(?:(?请注意-这将正确地允许重叠匹配,但将匹配比您的示例更多的有效序列。我提出了一个很难理解的方法,目前我没有时间解释。其想法是使用分支重置组在重叠
1
之间交替,但只消耗部分,直到最后一个
1
序列并捕获非重叠,无需前瞻。结果将在第1组中。谢谢大家!@bobblebubble您的解决方案
\b(?)(((?:1)+(\d?\d)\3+(?:1)*\3+(?:1)*)\2((\d?\d)\2+(?:1)*\2+(?:1)*)
太棒了!这就是我要找的!谢谢!!这回答了你的问题吗?很好,这对你有用。我在答案中添加了一些解释:)很好,对你有用。我在答案中添加了一些解释:)
\b(?|(?=(((?:1 )+(\d?\d )\3+(?:1 )*\3+)(?:1 )*))\2|((\d?\d )\2+(?:1 )*\2+(?:1 )*))