I'm terrible with regular expressions. I'm trying to replace this:
public static function camelize($word) {
return preg_replace('/(^|_)([a-z])/e', 'strtoupper("\\2")', $word);
}
with preg_replace_callback with an anonymous function. I don't understand what the \\2 is doing. Or for that matter exactly how preg_replace_callback works.
What would be the correct code for achieving this?
In a regular expression, you can "capture" parts of the matched string with
(brackets)
; in this case, you are capturing the(^|_)
and([a-z])
parts of the match. These are numbered starting at 1, so you have back-references 1 and 2. Match 0 is the whole matched string.The
/e
modifier takes a replacement string, and substitutes backslash followed by a number (e.g.\1
) with the appropriate back-reference - but because you're inside a string, you need to escape the backslash, so you get'\\1'
. It then (effectively) runseval
to run the resulting string as though it was PHP code (which is why it's being deprecated, because it's easy to useeval
in an insecure way).The
preg_replace_callback
function instead takes a callback function and passes it an array containing the matched back-references. So where you would have written'\\1'
, you instead access element 1 of that parameter - e.g. if you have an anonymous function of the formfunction($matches) { ... }
, the first back-reference is$matches[1]
inside that function.So a
/e
argument ofcould become a callback of
Or in your case
could become
Note that
$m
and$matches
are not magic names, they're just the parameter name I gave when declaring my callback functions. Also, you don't have to pass an anonymous function, it could be a function name as a string, or something of the formarray($object, $method)
, as with any callback in PHP, e.g.As with any function, you can't access variables outside your callback (from the surrounding scope) by default. When using an anonymous function, you can use the
use
keyword to import the variables you need to access, as discussed in the PHP manual. e.g. if the old argument wasthen the new callback might look like
Gotchas
preg_replace_callback
is instead of the/e
modifier on the regex, so you need to remove that flag from your "pattern" argument. So a pattern like/blah(.*)blah/mei
would become/blah(.*)blah/mi
./e
modifier used a variant ofaddslashes()
internally on the arguments, so some replacements usedstripslashes()
to remove it; in most cases, you probably want to remove the call tostripslashes
from your new callback.