diff --git a/src/Utils/Strings.php b/src/Utils/Strings.php index 44020c4a0..868680ecb 100644 --- a/src/Utils/Strings.php +++ b/src/Utils/Strings.php @@ -539,12 +539,15 @@ public static function replace( string|array $pattern, string|callable $replacement = '', int $limit = -1, + bool $captureOffset = false, + bool $unmatchedAsNull = false, ): string { if (is_object($replacement) || is_array($replacement)) { if (!is_callable($replacement, false, $textual)) { throw new Nette\InvalidStateException("Callback '$textual' is not callable."); } - return self::pcre('preg_replace_callback', [$pattern, $replacement, $subject, $limit]); + $flags = ($captureOffset ? PREG_OFFSET_CAPTURE : 0) | ($unmatchedAsNull ? PREG_UNMATCHED_AS_NULL : 0); + return self::pcre('preg_replace_callback', [$pattern, $replacement, $subject, $limit, 0, $flags]); } elseif (is_array($pattern) && is_string(key($pattern))) { $replacement = array_values($pattern); diff --git a/tests/Utils/Strings.replace().phpt b/tests/Utils/Strings.replace().phpt index 5dda17322..f64a2edb6 100644 --- a/tests/Utils/Strings.replace().phpt +++ b/tests/Utils/Strings.replace().phpt @@ -34,3 +34,5 @@ Assert::same('#@ @@@#d!', Strings::replace('hello world!', [ ])); Assert::same(' !', Strings::replace('hello world!', '#\w#')); Assert::same(' !', Strings::replace('hello world!', ['#\w#'])); +Assert::same('hell0o worl9d!', Strings::replace('hello world!', '#[e-l]+#', fn($m) => implode($m[0]), captureOffset: true)); +Strings::replace('hello world!', '#e(x)*#', fn($m) => Assert::null($m[1]), unmatchedAsNull: true);