preg_replace_callback_array()
版本:php7
(PHP 7)
Perform a regular expression search and replace using callbacks
说明
preg_replace_callback_array(array $patterns_and_callbacks, mixed $subject[,int $limit= -1[,int &$count]]): mixed
The behavior of this function is similar to preg_replace_callback(), except that callbacks are executed on a per-pattern basis.
参数
- $patterns_and_callbacks
An associative array mapping patterns(keys)to callbacks(values).
- $subject
The string or an array with strings to search and replace.
- $limit
The maximum possible replacements for each pattern in each$subjectstring. Defaults to-1(no limit).
- $count
If specified, this variable will be filled with the number of replacements done.
返回值
preg_replace_callback_array() returns an array if the$subjectparameter is an array, or a string otherwise. On errors the return value is NULL
If matches are found, the new subject will be returned, otherwise$subjectwill be returned unchanged.
范例
preg_replace_callback_array() example
<?php $subject = 'Aaaaaa Bbb'; preg_replace_callback_array( [ '~[a]+~i' => function ($match) { echo strlen($match[0]), ' matches for "a" found', PHP_EOL; }, '~[b]+~i' => function ($match) { echo strlen($match[0]), ' matches for "b" found', PHP_EOL; } ], $subject ); ?>
以上例程会输出:
6 matches for "a" found 3 matches for "b" found
参见
- PCRE Patterns
preg_replace_callback()
执行一个正则表达式搜索并且使用一个回调进行替换preg_quote()
转义正则表达式字符preg_replace()
执行一个正则表达式的搜索和替换preg_last_error()
返回最后一个PCRE正则执行产生的错误代码- Anonymous functions
- callback类型的信息
Based on some tests, I found these important traits of the function. (These would be nice to see documented as part of its spec, e.g. for confirmation. Without that, this is just experimental curiosity. Still better than guesswork, though! ;) ) 1. Changes cascade over a subject across callbacks, i.e. a change made to a subject by a callback will be seen by the next callback, if its pattern matches the changed subject. (But a change made by a previous call of the *same* callback (on any subject) will not be seen by that callback again.) 2. The pattern + callback pairs will be applied in the order of their appearance in $patterns_and_callbacks. 3. The callback can't be null (or '') for a quick shortcut for empty replacements. 4. Overall, the algorithm starts iterating over $patterns_and_callbacks, and then feeds each $subject to the current callback, repeatedly for every single match of its pattern on the current subject (unlike "preg_match_all", that is, which can do the same in one go, returning the accumulated results in an array). This basically means that the "crown jewel", an even more efficient function: "preg_replace_all_callback_array" is still missing from the collection. (Of course, that would better fit a new design of the regex API, where one API could flexibly handle various different modes via some $flags = [] array.) 5. (This last one is not specific to this function, but inherent to regexes, OTOH, it's probably more relevant here than anywhere else in PHP's regex support.) Even apparently simple cases can generate a crazy (and difficult-to-predict) number of matches, and therefore callback invokations, so remember the set $limit, where affordable. But, of course, try to sharpen your patterns first! E.g. use ^...$ anchoring to avoid unintended extra calls on matching substrings of a subject, (I.e. '/.*/', without anchoring, would match twice: once for the whole subject, and then for a trailing empty substring -- but I'm not quite sure this should actually be correct behavior, though.)
finally!!! before (<=php5.6): <?php $htmlString = preg_replace_callback( '/(href="?)(\S+)("?)/i', function (&$matches) { return $matches[1] . urldecode($matches[2]) . $matches[3]; }, $htmlString ); $htmlString = preg_replace_callback( '/(href="?\S+)(%24)(\S+)?"?/i', // %24 = $ function (&$matches) { return urldecode($matches[1] . '$' . $matches[3]); }, $htmlString ); ?> php7 <?php $htmlString = preg_replace_callback_array( [ '/(href="?)(\S+)("?)/i' => function (&$matches) { return $matches[1] . urldecode($matches[2]) . $matches[3]; }, '/(href="?\S+)(%24)(\S+)?"?/i' => function (&$matches) { return urldecode($matches[1] . '$' . $matches[3]); } ], $htmlString ); ?>
Here's a possible alternative in older PHP. <?php // if (!function_exists('preg_replace_callback_array')) { function preg_replace_callback_array (array $patterns_and_callbacks, $subject, $limit=-1, &$count=NULL) { $count = 0; foreach ($patterns_and_callbacks as $pattern => &$callback) { $subject = preg_replace_callback($pattern, $callback, $subject, $limit, $partial_count); $count += $partial_count; } return preg_last_error() == PREG_NO_ERROR ? $subject : NULL; } // } ?>