Okay, this works perfectly.
Code: Select all
$source = '11000001100010011000001';
$result = $source;
$searchOffset = 0;
while (preg_match('/(\A|1)(0{1,4})(1|\Z)/', $source, $match, PREG_OFFSET_CAPTURE, $searchOffset)) {
$length = strlen($match[2][0]);
$offset = $match[2][1];
$searchOffset = $offset + $length;
$replacement = str_pad('', $length, '1');
$result = substr_replace($result, $replacement, $offset, $length);
}
Do you see how it works? It keeps searching the $source string for a clump of zeros between 1 and 4 in size, making sure there's a one or the beginning before, and a one or the end after. Otherwise it would match larger clumps. PREG_OFFSET_CAPTURE is used so that we know where the match is found (see
http://php.net/preg-match). Next, it gets the necessary information from the match, and generates a clump of ones the correct length. Lastly, the replacement is made with substr_replace().
Note that upon every iteration, the $searchOffset is changed to the end of the current match. Otherwise, the loop would go on forever, always returning the first match.
http://php.net/substr-replace
http://php.net/str-pad