PHP将String替换为函数的Result

I have a PHP variable that contains HTML. I need to check for occourances of a string, and have that string replaced with the result of a function.

The function has not yet been written, but will only require one variable passed to it which will be the ID of the product.

For instance, the website has products, I want the user to be able to type something into the wysiwyg editor like {{product=68}} and it will display a preset div container with the information for that product. In this case the product has ID 68 in the database, but it could be anything from 1 to whatever.

I thought about creating an array of product id's and searching for the first part of the string, but felt it may be rather cumbersome, I think one of our resident reg exp genius may be able to shed some light on what i need to do.

So the question is... how do i search a string for occourances of {{product=XXX}} where XXX can be an integer higher than one, capture that number, and pass it to a function which creates the replacement string which ultimatley replaces the occourance of the string ?

Here is a regexp that matches {{product=##}} (doesn't matter how many digits you enter):

{{product=([0-9]+)}}

Edit: Sorry, didn't see you wanted it starting with 1:

{{product=([1-9][0-9]*)}}

If you want to capture the number, to it like this:

$string = '{{product=68}}';
preg_match_all( '%{{product=([1-9][0-9]*)}}%', $string, $matches );
$number = (int) $matches[1][0];

To give you a better understanding of preg_match_all, this is the content of $matches:

array
  [0] => array // An array with strings that matched the whole regexp
    [0] => '{{product=68}}'
  [1] => array // An array with strings that were in the first "match group", indicated by paranthesis in the regexp
    [0] => '68'

E.g. $matches would look like this if you had the string '{{product=68}}{{product=70}}':

array
  [0] => array
    [0] => '{{product=68}}'
    [1] => '{{product=70}}'
  [1] => array
    [0] => '68'
    [1] => '70'

Made a small class for you, that should do what you need.

<?php
class textParser{
    const _pattern = '/{{([a-z\-_]+)=([0-9]+)}}/';
    static protected $_data = false;

    static public function setData($data){
        self::$_data = $data;
    }
    static function parseStr($str){
        // Does a preg_replace according to the 'replace' callback, on all the matches
        return preg_replace_callback(self::_pattern, 'self::replace', $str);
    }
    protected static function replace($matches){
        // For instance, if string was {{product=1}}, we check if self::$_data['product'][1] is set
        // If it is, we return that
        if(isset(self::$_data[$matches[1]][$matches[2]])){
            return self::$_data[$matches[1]][$matches[2]];
        }
        // Otherwise, we just return the matched string
        return $matches[0];
    }
}
?>

Unit test / Basic usage

<?php
// User generated text-string
$text = "Item {{product=1}} and another {{category=4}} and a category that doesnt exist: {{category=15}}";
// This should probably come from a database or something
$data = array(
    "product"=>array(
        1=>"<div>Table</div>"
      , 2=>"<div>Tablecloth</div>"
    )
  , "category"=>array(
        4=>"Category stuff"
    )
);
// Setting the data
textParser::setData($data);
// Parsing and echoing
$formated = textParser::parseStr($text);
echo $formated;
// Item <div>Table</div> and another Category stuff and a category that doesnt exist: {{category=15}}
?>