Замените preg_replace () e модификатор на preg_replace_callback

Я ужасен с регулярными выражениями. Я пытаюсь заменить это:

public static function camelize($word) { return preg_replace('/(^|_)([az])/e', 'strtoupper("\\2")', $word); } 

с preg_replace_callback с анонимной функцией. Я не понимаю, что делает \\ 2. Или, в точности, как работает preg_replace_callback.

Каким будет правильный код для достижения этого?

В регулярном выражении вы можете «захватить» части согласованной строки (brackets) ; в этом случае вы захватываете (^|_) и ([az]) части матча. Они нумеруются начиная с 1, так что у вас есть обратные ссылки 1 и 2. Матч 0 – вся строка со строкой.

Модификатор /e принимает заменяющую строку и заменяет обратную косую черту с последующим номером (например, \1 ) с соответствующей обратной ссылкой – но поскольку вы внутри строки, вам нужно избежать обратного слэша, так что вы получите '\\1' . Затем он (эффективно) запускает eval для запуска результирующей строки, как если бы это был PHP-код (поэтому он устарел, потому что легко использовать eval в небезопасном режиме).

Функция preg_replace_callback вместо этого выполняет функцию обратного вызова и передает ей массив, содержащий согласованные обратные ссылки. Итак, где бы вы написали '\\1' , вы вместо этого обращаетесь к элементу 1 этого параметра – например, если у вас есть анонимная функция функции формы function($matches) { ... } , первая обратная ссылка – $matches[1] внутри этой функции.

Итак, аргумент a /e

 'do_stuff(\\1) . "and" . do_stuff(\\2)' 

может стать обратным вызовом

 function($m) { return do_stuff($m[1]) . "and" . do_stuff($m[2]); } 

Или в вашем случае

 'strtoupper("\\2")' 

мог стать

 function($m) { return strtoupper($m[2]); } 

Обратите внимание, что $matches $m и $matches не являются волшебными именами, это просто имя параметра, которое я дал при объявлении моих функций обратного вызова. Кроме того, вам не нужно передавать анонимную функцию, это может быть имя функции как строка или что-то вроде array($object, $method) формы array($object, $method) , как и любой обратный вызов в PHP , например

 function stuffy_callback($things) { return do_stuff($things[1]) . "and" . do_stuff($things[2]); } $foo = preg_replace_callback('/([az]+) and ([az]+)/', 'stuffy_callback', 'fish and chips'); 

Как и для любой функции, вы не можете получить доступ к переменным за пределами своего обратного вызова (из окружения) по умолчанию. При использовании анонимной функции вы можете использовать ключевое слово use для импорта переменных, которые вам нужны для доступа, как описано в руководстве по PHP . например, если старый аргумент был

 'do_stuff(\\1, $foo)' 

то новый обратный вызов может выглядеть так:

 function($m) use ($foo) { return do_stuff($m[1], $foo); } 

Gotchas

  • Использование preg_replace_callback вместо модификатора /e в регулярном выражении, поэтому вам нужно удалить этот флаг из аргумента «шаблон». Таким образом, шаблон, подобный /blah(.*)blah/mei , станет /blah(.*)blah/mi .
  • Модификатор /e использовал аргумент addslashes() внутри аргументов, поэтому для некоторых замен использовались stripslashes() для его удаления; в большинстве случаев вы, вероятно, хотите удалить вызов stripslashes из вашего нового обратного вызова.