Using preg_replace_callback in PHP for Regex Replacement with Callbacks
The article explains PHP’s preg_replace_callback function, detailing its parameters and behavior, and provides three practical examples that demonstrate using anonymous and named callbacks to transform input strings, increment dates, and recursively parse custom tags into nested HTML elements.
preg_replace_callback() performs a regular‑expression search and replaces matches using a user‑defined callback function, behaving like preg_replace() except that the replacement is generated by the callback.
Parameters: pattern (string or array to search), callback (callable that receives matches and returns the replacement string), subject (string or array to be processed), limit (maximum number of replacements per pattern, default -1 for unlimited), and count (optional variable that receives the number of replacements performed).
Example 1 reads lines from STDIN and converts the first character of each line to lowercase using an anonymous function as the callback.
<?php
$fp = fopen("php://stdin", "r") or die("can't read stdin");
while (!feof($fp)) {
$line = fgets($fp);
$line = preg_replace_callback('|<p>\s*\w|', function($matches) {
return strtolower($matches[0]);
}, $line);
echo $line;
}
fclose($fp);
?>Example 2 shows how to increment the year part of dates in a text by one using a named callback function next_year that adds one to the captured year group.
<?php
$text = "April fools day is 04/01/2020
";
$text = "Last christmas was 12/24/2020
";
function next_year($matches) {
// $matches[0] is the full match, $matches[1] is the month/day, $matches[2] is the year
return $matches[1] . ($matches[2] + 1);
}
echo preg_replace_callback("|(\d{2}/\d{2}/)(\d{4})|", "next_year", $text);
?>Example 3 demonstrates a recursive parsing of custom [indent]…[/indent] tags, converting them into nested <div> elements with increased left margin, using preg_replace_callback() together with a recursive function.
<?php
$input = "plain [indent] deep [indent] deeper [/indent] deep [/indent] plain";
function parseTagsRecursive($input) {
$regex = '#\[indent]((?:[^[]|\[(?!/?indent])|(?R))+?)\[/indent]#';
if (is_array($input)) {
$input = '<div style="margin-left:10px">' . $input[1] . '</div>';
}
return preg_replace_callback($regex, 'parseTagsRecursive', $input);
}
$output = parseTagsRecursive($input);
echo $output;
?>Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Laravel Tech Community
Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
