Web студия "GrandView"
  Главная   Написать Контакты
   
   
О проекте
Руководство php
 

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
 
// Этот текст был использован в 2002 году
  // мы хотим обновить даты к 2003 году
 
$text = "April fools day is 04/01/2002\n";
 
$text.= "Last christmas was 12/24/2001\n";

 
// функция обратного вызова
 
function next_year($matches)
  {
   
// как обычно: $matches[0] -  полное вхождение шаблона
    // $matches[1] - вхождение первой подмаски,
    // заключенной в круглые скобки, и так далее...
   
return $matches[1].($matches[2]+1);
  }

  echo
preg_replace_callback(
             
"|(\d{2}/\d{2}/)(\d{4})|",
             
"next_year",
             
$text);

 
// результат:
  // April fools day is 04/01/2003
  // Last christmas was 12/24/2002
?>

Достаточно часто callback функция, кроме как в вызове preg_replace_callback(), ни в чем больше не участвует. Исходя из этих соображений, можно использовать create_function() для создания безымянной функции обратного вызова непосредственно в вызове preg_replace_callback(). Если вы используете такой подход, вся информация, связанная с заменой по регулярному выражению, будет собрана в одном месте, и пространство имен функций не будет загромождаться неиспользуемыми записями.

Пример 2. preg_replace_callback() и create_function()

<?php
 
/* фильтр, подобный тому, что используется в системах Unix
   * для преобразования в заглавные начальных букв параграфа */

 
$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().



preg_replace> <preg_quote
Last updated: Sat, 27 Jan 2007
 
add a note 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; // store 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; // retrieve bar
       
        // do stuff like $bar->get_someothervar();
       
       
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

// v v over simplified
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();

/**
output is
<a class='whatever' href='http://someothersite.com/foo.php?page=http%3A%2F%2Ffoo.com' target='_blank'>foo</a>
*/

?>
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...

preg_replace> <preg_quote
Last updated: Sat, 27 Jan 2007
 
 
Новости
11 июля 2007
Сайт запущен
© 2007 info@grandviewstudio.com

Deprecated: Function set_magic_quotes_runtime() is deprecated in /home/sites/grandviewstudiocom/www/65f67d67a94ad980786580ae69e11c07/sape.php on line 324

Deprecated: Function set_magic_quotes_runtime() is deprecated in /home/sites/grandviewstudiocom/www/65f67d67a94ad980786580ae69e11c07/sape.php on line 330
Z058440144362 Z348613067571