Рассмотрим ниже рабочий код:
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
/*Below var_dump() outputs
array(2) {
[0]=>
string(2) "-w"[1]=>
string(1) "w"}
var_dump($match);*/
return strtoupper($match[1]);
}, 'hello-world');
// outputs helloWorld
?>
Приведенный выше код работает нормально и генерирует вывод. Но у меня есть проблема с пониманием того, что он работает в анонимной функции.
Мой вопрос заключается в том, почему анонимная функция не получает весь массив или строку, содержащую значение Привет, мир?
Почему он получает странный массив ниже?
Array
(
[0] => -w
[1] => w
)
Я просто добавляю другой (возможно, избыточный) ответ, потому что я думаю, что вы в основном неправильно понимаете задачу функции анонимного / обратного вызова. Supposed Это должно делать довольно мало.
В основном это логический поток:
Ваша входная строка 'hello-world'
Соответствует preg_replace_callback
И регулярное выражение только выдержки '-w'
от него.
Ваша функция обратного вызова получает только это совпадение, разбитое на $ match =["-w", "w"]
(@mickmack уже объяснил почему)
Предполагается, что анонимная функция работает только с соответствующей частью / выполняет замену с этим отрывком.
Это никогда не работает, и не нуждается во всем оригинальном вводе (hello-world
).
Так как он предназначен только для прописных букв первой буквы второго слова, работая на $match[1]
достаточно.
Таким образом, это только возвращает 'W'
Работа функции обратного вызова не является сделать его замену на всю / оригинальную строку.
это preg_replace_callback
который делает фактический задача замены на входной строке.
Это меняет регулярное выражение '-w'
в верхнем регистре 'W'
как возвращенный от вашей анонимной функции.
Как объяснил @ArtisticPhoenix, вы можете изменить регулярное выражение и соответствие, и ваш обратный вызов получит «лучшее представление» о выполняемой задаче.
Но опять же, для фактической цели вполне достаточно, если ваш обратный вызов просто видит одну букву и только возвращает ее.
Здесь я объясню это.
Ваш Регкс '~-([a-z])~'
говорит:
-
буквальный, матч -
один раз.(..)
захватить группу, вернуть результаты матча.[a-z]
набор символов, соответствие a
через z
один раз.Аргумент обратного вызова основан на совпадениях. Вы получаете матч 0
а также 1
, 0
это все, что соответствует Регкс (включая -
). 1
это все в first
захватить группу.
Поэтому, когда вы даете это hello-world
Матч начинается с -
и заканчивается после первого [a-z]
или в этом случае w
,
Теперь, если вы добавили еще одну группу захвата, то у вас будет совпадение 2
, Например:
'~-([a-z])([a-z])~'
Вы бы получили что-то вроде [0=>'-wo', 1=>'w',2=>'o']
вместо.
Проверьте это онлайн, здесь: https://regex101.com/r/yakHNF/1
Если бы вы изменили его на
'~-([a-z]+)~'
Это дало бы вам [0=>'-world', 1=>'world']
, поскольку +
соответствует одному или нескольким разам, поэтому соответствует целому слову.
«Полное соответствие» ( [0]
элемент в выходном массиве) является неизбежным. Что ты Можно избегать (чтобы уменьшить раздувание выходного массива и повысить эффективность регулярных выражений) является использование группы захвата. Вам нужно сопоставить дефис и букву и вернуть только букву — таким образом дефис будет удален.
Вот эквивалентный метод без выходного массива: (демонстрация)
echo preg_replace_callback('~-[a-z]~', function ($match) {
/*Below var_export() outputs only the "fullstring" match (no capture groups)
array (
0 => '-w',
)
var_export($match); */
return strtoupper($match[0][1]); // return only the character at offset 1 (2nd char)
}, 'hello-world');
Выход:
helloWorld