tags:

views:

73

answers:

3

Hi,

I'm writing an application in PHP, and I need to replace any word between <!-- * and * --> with it's correspondenting element in $vars. For example,

<!-- *foobar* -->

In this case 'foobar' must be replaced by the variable $vars["foobar"]'s value. This is what I have now, but it does not work (it always returns <> :( ):

preg_replace_callback("<!--(\s+)\*([a-zA-Z0-9]+)\*(\s+)-->", create_function('$matches', 'return $vars[$matches];'), $template);

Can anyone help me? Thanks in advance.

+1  A: 

Try:

create_function('$matches', 'return $vars[$matches[2]];')

since the second group is the one you want. Not sure why you're capturing the others however. Also for this kind of thing I tend to prefer a global rather than calling create_function().

Also, you're not delimiting the regex, like this version with /:

$vars = array(...);
preg_replace_callback('/<!--\s+\*([a-zA-Z0-9]+)\*\s+-->/', 'replace_var', $template);

function replace_var($matches) {
  global $vars;
  return $vars[$matches[1]];
}
cletus
Sorry, doesn't work for me.
Time Machine
To be honest, I'd just use `/e` rather than a callback...
Matthew Scharley
A: 

I think what you need is:

preg_replace_callback("/<!--\s+\*([a-zA-Z0-9]+)\*\s+-->/", create_function('$matches', 'return $vars[$matches[2]];'), $template);

The $matches variable is an array. Index 0 is what matched the whole regex and then any further indexes are the capture groups (if any) in the regex.

In this case $matches will look like this:

array(2) {
  [0]=>
  string(18) "<!-- *example* -->"
  [1]=>
  string(7) "example"
}
Seb Pollard
Sorry, doesn't work. Maybe it's the regex itself.
Time Machine
+4  A: 

Remember that you can't use $vars without introducing at with global keyword or by using $GLOBALS. Also if you're running PHP 5.3, you can use an anonymous function without an ugly global hack:

$template = preg_replace_callback('/<!--\s+\*(\w+)\*\s+-->/', function($matches) use ($vars) { return $vars[$matches[1]]; }, $template);

In pre-5.3 you can do this:

$template = preg_replace_callback('/<!--\s+\*(\w+)\*\s+-->/', create_function('$matches', 'return $GLOBALS["vars"][$matches[1]];'), $template);

If you don't run 5.3 but still want to avoid global variable, you can do this:

$template = preg_replace('/<!--\s+\*(\w+)\*\s+-->/e', '$vars["\1"]', $template);
reko_t
Thanks, the third example worked!
Time Machine