|
|
preg_replace_callback (PHP 4 >= 4.0.5, PHP 5) preg_replace_callback -- Выполняет поиск по регулярному выражению и замену с использованием функции обратного вызова Описаниеmixed preg_replace_callback ( mixed pattern, callback callback, mixed subject [, int limit] )
Поведение этой функции во многом напоминает
preg_replace(), за исключением того, что вместо
параметра replacement необходимо указывать
callback функцию, которой в качестве
входящего параметра передается массив найденных вхождений.
Ожидаемый результат - строка, которой будет произведена замена.
Пример 1. preg_replace_callback() пример |
<?php
$text = "April fools day is 04/01/2002\n";
$text.= "Last christmas was 12/24/2001\n";
function next_year($matches)
{
return $matches[1].($matches[2]+1);
}
echo preg_replace_callback(
"|(\d{2}/\d{2}/)(\d{4})|",
"next_year",
$text);
?>
|
|
Достаточно часто callback функция, кроме как в вызове
preg_replace_callback(), ни в чем больше не участвует.
Исходя из этих соображений, можно использовать create_function()
для создания безымянной функции обратного вызова непосредственно
в вызове preg_replace_callback().
Если вы используете такой подход, вся информация, связанная с заменой по
регулярному выражению, будет собрана в одном месте, и пространство имен
функций не будет загромождаться неиспользуемыми записями.
Пример 2. preg_replace_callback() и create_function() |
<?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|',
create_function(
'$matches',
'return strtolower($matches[0]);'
),
$line
);
echo $line;
}
fclose($fp);
?>
|
|
Смотрите также preg_replace() и
create_function().
add a note
User Contributed Notes
preg_replace_callback
vinyanov at poczta dot onet dot pl
26-Sep-2007 03:34
If you want to replace your matches with a unique calculation and you do not want to use:
1. preg_replace() and /e flag*
2. preg_replace_callback() and create_function()**
3. preg_replace_callback() and fill the namespace with an additional function
You can insert both call and solution within one function. Then, you may supply callback with the __FUNCTION__ predefined constant, and the function will separate its responsibilities itself by the type of the argument. Since preg_replace_callback() returns an array, this is easy. Quite useless example:
<?php
function debug($s)
{
if(is_string($s))
{
return preg_replace_callback('/{\?(cl|co|f|i|v)}/', __FUNCTION__, $s);
}
foreach(array(
'co' =>'nstants',
'f' =>'unctions',
'v' =>'ars',
'cl' =>'asses',
'i' =>'nterfaces',
) as $p[1] => $p[2])
{
if($p[1] === $s[1])
{
$p[0] = in_array($p[1], array('cl', 'i')) ? 'declared' : 'defined';
$f = vsprintf('get_%3$s_%2$s%1$s', $p); return var_export($f(), 1);
}
}
}
echo debug('Variables: {?v} Nothing: {?n} Interfaces: {?i}');
?>
* I do not know whether it evokes eval() or not
** http://tinyurl.com/3azwyy
ak at optimumenglish dot com
12-Sep-2007 10:09
Add this snippet to your callback function to make sure you don't replace HTML code. Useful when searching / replacing / highlighting HTML. Change 90 to whatever threshold you need if you have extra extra long tags for some weird reason (lots of inline styles?)
function scanForTags($position, $maintext)
{
for($i = 1;$i < 90; $i++)
{
if($maintext{$position-$i} == "<" || $maintext{$position+$i} == ">")
return true;
if($maintext{$position-$i} == ">" || $maintext{$position+$i} == "<")
return false;
}
return false;
}
roytam at NOSPAM dot gmail dot com
13-Jul-2007 03:57
> sjungwirth domain matrix-consultants com
It may fail in nested condition if $bar needs to be changed.
Sjon at hortensius dot net
24-Jun-2007 04:56
preg_replace_callback returns NULL when pcre.backtrack_limit is reached; this sometimes occurs faster then you might expect. No error is raised either; so don't forget to check for NULL yourself
sjungwirth domain matrix-consultants com
06-May-2007 05:31
one way to 'pass' extra info other than just the matches and still use preg_replace_callback is to have your callback function be a class method, and just before you call preg_replace_callback, store the info in that class. I am using static methods/variables for my implementation; I'm not sure if its required.
<?php
class foo {
private static $bar;
public static function do_something($bar) {
self::$bar = $bar; $input = $bar->get_somevar();
$pattern = "match me";
$output = preg_replace_callback($pattern, array('self', 'do_something_callback'), $input);
return $output;
}
private static function do_something_callback($matches) {
$bar = self::$bar; return $replacement;
}
}
?>
matt at mattsoft dot net
26-Apr-2006 02:16
it is much better on preformance and better practice to use the preg_replace_callback function instead of preg_replace with the e modifier.
function a($text){return($text);}
// 2.76 seconds to run 50000 times
preg_replace("/\{(.*?)\}/e","a('\\1','\\2','\\3',\$b)",$a);
// 0.97 seconds to run 50000 times
preg_replace_callback("/\{(.*?)\}/s","a",$a);
spamhoneypot at acksys dot co dot uk
16-Dec-2003 06:08
I thought I'd post this as I'd been using the function preg_replace_callback with NP within functions, but as soon as I re-wrote my script as a class, it all fell apart.
When debugging I ended up writing test code and this is what follows. It works as I'd expect, YMMV of course.
<?php
class foo
{
function parse()
{
$pattern = "/<a(.*?)href\s*=\s*['|\"|\s*](.*?)['|\"|>](.*?)>(.*?)<\/a>/i";
$string = "<a class='whatever' href='http://foo.com' target='_blank'>foo</a>";
print preg_replace_callback($pattern,array($this,'cb'),$string);
}
function cb($matches)
{
return "<a" . $matches[1] . "href='http://someothersite.com/foo.php?page=" . urlencode($matches[2]) . "'" . $matches[3] . ">" . $matches[4] . "</a>";
}
}
$bar = new foo();
$bar->parse();
?>
vlad4321 at fastmail dot fm
11-Nov-2003 03:47
You can use this function to display url address as a link or image based on suffix of the url.
Every string beginning with www or http(s):// will be displayed as an URL address. But if the string ends with *.jpg or *.gif, it will be displayed as an image.
Please note: This function also verifies the size of the image. If is it more than 600x400, it changes it.
<?php
$pattern_html = "/\b((http(s?):\/\/)|(www\.))([\w\.]+)";
$pattern_html .= "([\#\,\/\~\?\&\=\;\%\-\w+\.]+)\b/i";
$text = preg_replace_callback($pattern_html,'Check_if_Image',$text);
.
.
function Check_if_Image($matches) {
$suffix = strtolower(substr($matches[0],-4));
if ( $suffix == '.jpg' or $suffix == '.gif') {
$dsn = 'http'.$matches[3].'://'.$matches[4].$matches[5];
if (list($width, $height, $type, $attr) = getimagesize("$dsn")) {
if ( ($width > 600) ) {
$koef = $width / 600;
$width = 600;
$height /= $koef;
}
if ( ($height > 400) ) {
$koef = $height / 400;
$height = 400;
$width /= $koef;
}
}
else {
$height=400;
$width=600;
}
$ret = "<img src=\"$dsn\"";
$ret .= "\" border=0 width=\"$width\" height=\"$height\">";
}
else {
$ret = '<a href="http'.$matches[3].'://'.$matches[4].$matches[5];
$ret .='" target="_blank">'.$matches[0].'</a>';
}
return ("$ret");
}
?>
e-mail at dreamguard dot at
23-Oct-2003 02:02
If you want to do a date function in a template system you'll have to use the callback here.
Ex.:
function date_match ($matches)
{
return date ($matches['2']);
}
$output = preg_replace_callback ('/({DATE=")(.{1,})("})/', 'date_match', $input);
oyoryelNOSPAM at hotNOSPAMmail dot com
21-Apr-2002 09:23
If you want to be able to change variables of the class in the callback function, you have to use preg_replace_callback(pattern, array(&$this, 'method_name'), subject)
Probably very obvious, but it kept me busy for a while...
|