in src/regex/regex.php [140:173]
function replace_with<T as Match>(
string $haystack,
Pattern<T> $pattern,
(function(T)[_]: string) $replace_func,
int $offset = 0,
)[ctx $replace_func]: string {
$haystack_length = Str\length($haystack);
$result = Str\slice($haystack, 0, 0);
$match_end = 0;
while (true) {
$match = _Private\regex_match($haystack, $pattern, inout $offset);
if ($match === null) {
break;
}
// Copy anything between the previous match and this one
$result .= Str\slice($haystack, $match_end, $offset - $match_end);
$result .= $replace_func($match);
$match_length = Str\length(Shapes::at($match, 0) as string);
$match_end = $offset + $match_length;
if ($match_length === 0) {
// To get the next match (and avoid looping forever), need to skip forward
// before searching again
// Note that `$offset` is for searching and `$match_end` is for copying
$offset++;
if ($offset > $haystack_length) {
break;
}
} else {
$offset = $match_end;
}
}
$result .= Str\slice($haystack, $match_end);
return $result;
}