PHP Regular Expressions
Using a PHP Function in a Regular Expression
Problem
You want to process matched text with a PHP function. For example, you want to decode all HTML entities in captured subpatterns.
Solution
Use preg_replace_callback(). Instead of a replacement pattern, give it a callback function. This callback function is passed an array of matched subpatterns and should return an appropriate replacement string.
Example Generating replacement strings with a callback function
$h = 'The <b> tag makes text bold: <code><b>bold</b></code>';
print preg_replace_callback('@<code>(.*?)</code>@','decode', $h);
// $matches[0] is the entire matched string
// $matches[1] is the first captured subpattern
function decode($matches) {
return html_entity_decode($matches[1]);
}
Example prints:
The <b> tag makes text bold: <b>bold</b>
Discussion
The second argument to preg_replace_callback() specifies the function that is to be called to calculate replacement strings. Like everywhere the PHP “callable” pseudotype is used, this argument can be a string or an array. Use a string to specify a function name.
To use an object instance method as a callback, pass an array whose first element is the object and whose second element is a string containing the method name. To use a static class method as a callback, pass an array of two strings: the class name and the method name. In PHP 5.4.0 and later, you can pass a variable containing an anonymous function, or define the function inline with the call to preg_replace_callback().
The callback function is passed one argument: an array of matches. Element 0 of this array is always the text that matched the entire pattern. If the pattern given to preg_replace_callback() has any parenthesized subpatterns, these are present in subsequent elements of the $matches array. The keys of the $matches array are numeric, even if there are named subpatterns in the pattern.
If you are providing an anonymous function as a callback, it can be memory intensive if the function creation is inline with the call to preg_replace_callback() and inside a loop. If you want to use an anonymous function with preg_replace_callback(), store the anonymous function callback in a variable. Then, provide the variable to preg_replace_callback() as the callback function.
Example Generating replacement strings with an anonymous function
$callbackFunction = function($matches) {
return html_entity_decode($matches[1]);
};
$fp = fopen(__DIR__ . '/html-to-decode.html','r');
while (! feof($fp)) {
$line = fgets($fp);
print preg_replace_callback('@<code>(.*?)</code>@',$callbackFunction, $line);
}
fclose($fp);
Uses the anonymous function declaration syntax introduced in PHP 5.3.0. If you’re using an older version of PHP, you can use create_function() to build your callback, as follows:
$callbackFunction = create_function('$matches',
'return html_entity_decode($matches[1]);');
$fp = fopen(__DIR__ . '/html-to-decode.html','r');
while (! feof($fp)) {
$line = fgets($fp);
print preg_replace_callback('@<code>(.*?)</code>@',$callbackFunction, $line);
}
fclose($fp);
So you can avoid using it, you should be aware of the e pattern modifier. This causes the replacement string to be evaluated as PHP code. This pattern modifier is deprecated as of PHP 5.5.0. Using the e modifier opens up remote code execution security vulnerabilities when user input is part of the text that preg_replace() operates on. If you encounter code using preg_replace() with the e modifier, convert it to use preg_replace_callback() instead.
No comments:
Post a Comment