1

Say I have this HTML:

        <html>
            <head>
                <title>Hello [[USER_FIRST_NAME]]</title>
            </head>
            <body>
                <p>Hi, [[USER_FIRST_NAME]] [[USER_LAST_NAME]]!</p>
                <p><a href="mailto:[[USER_EMAIL]]">[[USER_EMAIL]]</a></p>
            </body>
        </html>

I need to preg_replace all those [[FOOBAR]] tokens with values.

End result:

        <html>
            <head>
                <title>Hello John</title>
            </head>
            <body>
                <p>Hi, John Smith!</p>
                <p><a href="mailto:john@smith.com">john@smith.com</a></p>
            </body>
        </html>
Maverick
  • 3,039
  • 6
  • 26
  • 35
  • possible duplicate of [multiple preg_replace on the same variable](http://stackoverflow.com/questions/7144273/multiple-preg-replace-on-the-same-variable) – hakre Nov 18 '11 at 01:51
  • It's not a duplicate - I'm actually trying to figure out the matching of these strings. – Maverick Nov 18 '11 at 02:04
  • Yeah not the best duplicate. There is another one which uses `{{}}` around template vars but I was not able to find it. But the answer is basically the same. I added one answer here as well which is the same. – hakre Nov 18 '11 at 02:06

4 Answers4

10

The php function strtr is a good alternative to preg_replace for your case. Some example:

$tokens = array(
    'USER_FIRST_NAME' => 'John',
    'USER_EMAIL' => 'john@smith.com',
);

$pattern = '[[%s]]';

$map = array();
foreach($tokens as $var => $value)
{
    $map[sprintf($pattern, $var)] = $value;
}

$output = strtr($template, $map);

Basically the same answer as in multiple preg_replace on the same variable. See as well Efficient way to replace placeholders with variables.

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
3

No need for regex here:

$data_map = array(
    '[[USER_FIRST_NAME]]' => 'John',
    '[[USER_LAST_NAME]]' => 'Smith',
    '[[USER_EMAIL]]' => 'john@smith.com'
);

$html = <<<HTML
        <html>
            <head>
                <title>Hello [[USER_FIRST_NAME]]</title>
            </head>
            <body>
                <p>Hi, [[USER_FIRST_NAME]] [[USER_LAST_NAME]]!</p>
                <p><a href="mailto:[[USER_EMAIL]]">[[USER_EMAIL]]</a></p>
            </body>
        </html>
HTML;

$html = str_replace(array_keys($data_map), array_values($data_map), $html);
AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
  • 1
    `str_replace` will replace one after the other so you can have side-effects if the values contain data with the same pattern as another variable. – hakre Nov 18 '11 at 02:13
1

You would need to do that in a loop like this:

<?php

$html = ' <html>
            <head>
                <title>Hello [[USER_FIRST_NAME]]</title>
            </head>
            <body>
                <p>Hi, [[USER_FIRST_NAME]] [[USER_LAST_NAME]]!</p>
                <p><a href="mailto:[[USER_EMAIL]]">[[USER_EMAIL]]</a></p>
            </body>
        </html>';

$replacements = array(
    'USER_FIRST_NAME' => 'John',
    'USER_LAST_NAME' => 'Smith',
    'USER_EMAIL' => 'john@smith.com',
);

foreach($replacements as $find => $replace)
{
    $html = preg_replace('/\[\[' . preg_quote($find, '/') . '\]\]/', $replace, $html);
}

echo $html;
David Gallagher
  • 723
  • 4
  • 8
  • Actually it doesn't appear that you have any reason for using regular expressions here. Something like what @hakre linked to above would be better. – David Gallagher Nov 18 '11 at 01:59
1

Maybe you are looking to do something more like this. This has the advantage of replacing all unknown tokens or if you wish you could throw an exception or something.

You could also modify the regular expression to allow for a special escape sequence (on the off chance you ever wanted to include [[ or ]] in an email.)

You could also change your regular expression to '/\[\[(\w+)\]\]/' if you are looking for more strict matching.

<?php

$html = ' <html>
            <head>
                <title>Hello [[USER_FIRST_NAME]]</title>
            </head>
            <body>
                <p>Hi, [[USER_FIRST_NAME]] [[USER_LAST_NAME]]!</p>
                <p><a href="mailto:[[USER_EMAIL]]">[[USER_EMAIL]]</a></p>
            </body>
        </html>';


function replaceTokens($token)
{
    $replacements = array(
        'USER_FIRST_NAME' => 'John',
        'USER_LAST_NAME' => 'Smith',
        'USER_EMAIL' => 'john@smith.com',
    );

    if(isset($replacements[$token[1]]))
    {
        return $replacements[$token[1]];
    }
    else
    {
        return '';
    }
}

$html = preg_replace_callback('/\[\[(.*?)\]\]/', 'replaceTokens', $html);
echo $html;
David Gallagher
  • 723
  • 4
  • 8