views:

57

answers:

2

I need to replace "{Z}" with "test(Z)" where Z is always an unsigned integer using PHP and regular expressions (unless there's a faster way?).

$code='{45} == {2}->val() - {5}->val()';
// apply regex to $code
echo $code;
// writes: test(45) == test(2)->val() - test(5)->val()

The tricky part is that it needs to be done in the best manner possible concerning speed and memory use.

+4  A: 
$code = preg_replace('/\{(\d+)\}/', 'test($1)', $code);

In my experience, preg_replace is much faster than any method of doing replacements using str_replace or strtr.

amphetamachine
+4  A: 

The missing line is this:

$code = preg_replace('/{([0-9]+)}/', 'test($1)', $code);

How it works:

{       match a literal {
(       start a capturing group
[0-9]+  one or more digits in 0-9
)       end the capturing group
}       match a literal }

The $1 in the replacement string refers to the string captured by the first (and only) capturing group.

Mark Byers
Use `\d`; let's not begin teaching bad habits.
amphetamachine
This one seems to work perfectly.
Christian Sciberras
@amphetamachine: I'd say that if you actually mean digits in 0-9 then you should write `[0-9]`. This makes it very clear that you're only interested in those specific digits and not some other character that could be interpreted as a digit. In this case it doesn't make much difference, but I don't see why being explicit is a "bad habit". Perhaps you could explain your reasoning?
Mark Byers
@Mark Byers: Larry Wall decided that `\d` is easier to type and less error-prone than typing `[0-9]`. They mean the same thing.
amphetamachine