Sometimes you don't just want to cherry-pick the matches but need that the entire subject is made up from matching substrings, so every character of the subject is a member of a match. None of the existing preg_* function is easily applicable for this task, so I made the preg_match_entire() function.
It uses the (*MARK) syntax which is documented here: https://pcre.org/original/doc/html/pcrepattern.html#SEC27
<?php
function preg_match_entire( string $pattern, string $subject, int $flags = 0 ){
$delimiter = $pattern[0];
$ldp = strrpos( $pattern, $delimiter );
$pattern = substr( $pattern, 1, $ldp - 1 );
$modifiers = substr( $pattern, $ldp + 1 );
$pattern = "{$delimiter} \G\z (*MARK:END) | \G (?:{$pattern}) {$delimiter}x{$modifiers}";
$r = preg_match_all( $pattern, $subject, $m, PREG_SET_ORDER | $flags );
if( $r === false ) return false; $end = array_pop( $m );
if( $end === null || ! isset( $end['MARK']) || $end['MARK'] !== 'END')
return null; return $m; }
test('#{\d+}#', ''); test('#{\d+}#', '{11}{22}{33}'); test('#{\d+}#', '{11}{}{aa}{22},{{33}}');
function test( $pattern, $subject ){
echo "pattern: $pattern\n";
echo "subject: $subject\n";
print_matches('preg_match_entire: ', preg_match_entire( $pattern, $subject ));
preg_match_all( $pattern, $subject, $matches, PREG_SET_ORDER );
print_matches('preg_match_all: ', $matches );
echo "\n";
}
function print_matches( $t, $m ){
echo $t, is_array( $m ) && $m ? implode(',', array_column( $m, 0 )) : json_encode( $m ), "\n";
} ?>