How can I keep track of the current match’s offset from the start of the string in the callback of preg_replace_callback
?
For example, in this code, I’d like to point to the location of the match that throws the exception:
$substituted = preg_replace_callback('/{([a-z]+)}/', function ($match) use ($vars) {
$name = $match[1];
if (isset($vars[$name])) {
return $vars[$name];
}
$offset = /* ? */;
throw new Exception("undefined variable $name at byte $offset of template");
}, $template);
As of PHP 7.4.0, preg_replace_callback
also accepts the PREG_OFFSET_CAPTURE
flag, turning every match group into a [text, offset]
pair:
$substituted = preg_replace_callback('/{([a-z]+)}/', function ($match) use ($vars) {
$name = $match[1][0];
if (isset($vars[$name])) {
return $vars[$name];
}
$offset = $match[0][1];
throw new Exception("undefined variable $name at byte $offset of template");
}, $template, flags: PREG_OFFSET_CAPTURE);