5

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.

amphetamachine
  • 27,620
  • 12
  • 60
  • 72
Christian
  • 27,509
  • 17
  • 111
  • 155

2 Answers2

8

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
  • 811,555
  • 193
  • 1,581
  • 1,452
  • 1
    @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 Jul 11 '10 at 23:53
  • Larry Wall decided that `\d` is easier to type and less error-prone than typing `[0-9]`. They mean the same thing. – amphetamachine Jul 12 '10 at 00:20
5
$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
  • 27,620
  • 12
  • 60
  • 72