Почему анонимная функция не получает весь массив или строку, переданные ей в качестве аргумента в следующей программе?

Рассмотрим ниже рабочий код:

<?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
)

0

Решение

Я просто добавляю другой (возможно, избыточный) ответ, потому что я думаю, что вы в основном неправильно понимаете задачу функции анонимного / обратного вызова. Supposed Это должно делать довольно мало.

В основном это логический поток:

  1. Ваша входная строка 'hello-world'

  2. Соответствует preg_replace_callback

  3. И регулярное выражение только выдержки '-w' от него.

  4. Ваша функция обратного вызова получает только это совпадение, разбитое на $ match =["-w", "w"]
    (@mickmack уже объяснил почему)

  5. Предполагается, что анонимная функция работает только с соответствующей частью / выполняет замену с этим отрывком.

    • Это никогда не работает, и не нуждается во всем оригинальном вводе (hello-world).

    • Так как он предназначен только для прописных букв первой буквы второго слова, работая на $match[1] достаточно.

    • Таким образом, это только возвращает 'W'

    • Работа функции обратного вызова не является сделать его замену на всю / оригинальную строку.

  6. это preg_replace_callback который делает фактический задача замены на входной строке.

    • Это меняет регулярное выражение '-w' в верхнем регистре 'W' как возвращенный от вашей анонимной функции.

    • Как объяснил @ArtisticPhoenix, вы можете изменить регулярное выражение и соответствие, и ваш обратный вызов получит «лучшее представление» о выполняемой задаче.

Но опять же, для фактической цели вполне достаточно, если ваш обратный вызов просто видит одну букву и только возвращает ее.

0

Другие решения

Здесь я объясню это.

Ваш Регкс '~-([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'], поскольку + соответствует одному или нескольким разам, поэтому соответствует целому слову.

1

«Полное соответствие» ( [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
1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector