PCRE regular expression overlapping matches

A common trick is to use capturing technique inside an unanchored positive lookahead. Use this regex with preg_match_all:

(?=(1....1))

See regex demo

The values are in $matches[1]:

$re = "/(?=(1....1))/"; 
$str = "001110000100001100001"; 
preg_match_all($re, $str, $matches);
print_r($matches[1]);

See lookahead reference:

Lookaround actually matches characters, but then gives up the match, returning only the result: match or no match. That is why they are called "assertions". They do not consume characters in the string, but only assert whether a match is possible or not.

If you want to store the match of the regex inside a lookahead, you have to put capturing parentheses around the regex inside the lookahead, like this: (?=(regex)).


You can also do it using the \K feature (that refers to where the returned result begins) inside a lookbehind:

(?<=\K1)....1

demo

This way, you don't need to create a capture group, and since all characters are consumed (except the first that is in the lookbehind), the regex engine doesn't have to retry the pattern for the next five positions after a success.

$str = '001110000100001100001';

preg_match_all('~ (?<= \K 1 ) .... 1 ~x', $str, $matches);

print_r($matches[0]);

code

Note that if you are sure the second character is always a zero, using 0(?<=\K10)...1 is more performant because the pattern starts with a literal character and pcre is able to optimize it with a quick search of possible positions in the subject string.