tags:

views:

88

answers:

4

simple one really, i've written a regular expression to find and replace tags with php constants from within a html snippet. my solution, which works, just doesn't feel right. how can this be improved?

preg_match_all('/\{CONSTANT_(.*)\}/', $final, $result, PREG_PATTERN_ORDER);
            for ($i = 0; $i < count($result[1]); $i++) {
               $final = str_replace($result[0][$i], constant($result[1][$i]),$final);
            }
A: 

I'm always against reinventing the wheel: if you need some sort of template engine (which php already is) take a look at Smarty.

Keeper
this is true but implementing Smarty just seems overkill for this usage and presumably comes with its own inherent overhead anyway
seengee
A: 

What about

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit= -1 [, int &$count ]] )

?

The MYYN
A: 

Be careful with using ".*" in a regular expression, as it will greedily match everything it finds. For example, in the following line:

{CONSTANT_ONE} blah {CONSTANT_TWO}

The above regular expression will capture the string "ONE} blah {CONSTANT_TWO"

You could use a character class instead of . to match anything except a "}" character:

/\{CONSTANT_([^}]*)\}/
Adam Batkin
good point! thanks for the heads up
seengee
Surely you could just use the none greedy operator in a preg, e.g. .*?
Wesley Mason
+1  A: 

You can do it all in one hit with preg_replace_callback

function getConstant($matches) 
{
    return constant($matches[1]);
}
$final=preg_replace_callback(
           '/\{CONSTANT_(.*?)\}/',
           "getConstant",
           $final);

Note I've made the .* non greedy with .*?, this will have the effect of ensuring it doesn't go eating a } if a longer match is possible. You could get the same effect with ([^}]*), or better yet, ([a-zA-Z0-9_]+)

Paul Dixon
yeah, that looks like just what i need actually. seems more elegant and efficient
seengee
"[^}]}+" is even better than "(.*?)\}"
Tomalak