tags:

views:

195

answers:

4

I'd like to be able to replace things in a file with a regular expression using the following scheme:

I have an array:

$data = array(
  'title' => 'My Cool Title',
  'content' => ''
)

I also have a template (for clarity's sake, we'll assume the below is assigned to a variable $template)

<html>
<title><% title %></title>
<body><% content %></body>
</html>

I'd like to be able to use one regular expression to do the whole thing, so it can be as general as possible; The following is my stab at it (which doesn't work)

$endMarkup = preg_replace('/<% ([a-z]+) %>/',$data["\\1"], $template);

Is there a clean solution for putting associative array data into a template by array index?

+3  A: 

With a little work before hand you can do it with a single preg_replace call:

$replacements = array();
foreach ($data as $search => $replacement) {
   $replacements["/<% $search %>/"] = $replacement;
}
$endMarkup = preg_replace(
     array_keys($replacements), 
     array_values($replacements), 
     $template);
Allain Lalonde
With this method you could just use str_replace().
yjerem
Thanks Jeremy, you beat me to the edit;
Issac Kelly
Absolutely. I'd probably go with $replacements["/<% ?$search ?%>/i"] = $replacement; and then it'd be worth using regexes.
Allain Lalonde
If you cant verify or vouch for the titles you should use preg_quote. print_r(array("df+g?/4dd4" => 3));
OIS
A: 

You can do this with preg_replace_callback(). Here is how I'd do it:

function get_data($matches) {
    global $data;

    return $data[$matches[1]];
}

$endMarkup = preg_replace_callback('/<% ([a-z]+) %>/', 'get_data', $template);

Or all in one line using create_function() if you prefer:

$endMarkup = preg_replace_callback('/<% ([a-z]+) %>/', create_function('$matches', 'global $data; return $data[$matches[1]];'), $template);
yjerem
+1  A: 

You could try without regex if you wanted to. The function str_replace was made for this. If you don't understand regex this will be the best option for you.

Test data:

$data = array(
  'title' => 'My Cool Title',
  'content' => ''
);

$file = <<< EOF
<html>
<title><% title %></title>
<body><% content %></body>
</html>
EOF;

Function and example:

function replace_template($template, $data)
{
    $replace = array_fill(0, count($data), '<%% %s %%>');
    $keys = array_map('sprintf', $replace, array_keys($data));
    $output = str_replace($keys, $data, $template);
    return $output;
}

echo replace_template($file, $data);
OIS
A: 

Why do you want to bother with templating at all? PHP already is a templating language. Unless you're trying to rule out the possibility of code execution, everything you need is built into the language.

You can write your templates using plain PHP with short tags. You can wrap it all in a function to limit variable scope a bit. You can use import() to get a handful of variables out of an array. You can use include or require() to handle loading, parsing & inserting values into the file. You can use output buffering (ob_start()/ob_end()) to handle capturing the output in a string. Everything's built in, fast & thoroughly tested.

Sean McSomething