preg_replace_callback_array
Функция preg_replace_callback_array() в PHP позволяет заменять совпадения нескольких регулярных выражений за один вызов с собственным callback для каждого шаблона.
Введение
В PHP регулярные выражения — незаменимый инструмент для сопоставления, поиска и преобразования строк. Доступная начиная с PHP 7.1, функция preg_replace_callback_array() позволяет заменить все совпадения нескольких шаблонов регулярных выражений за один вызов, причём каждый шаблон имеет собственный callback, вычисляющий замену. Это вариант preg_replace_callback(), управляемый массивом: вместо одного шаблона и одного callback передаётся отображение пар шаблон => callback.
В этой главе описывается возвращаемое значение функции, разбираются её параметры и приводятся рабочие примеры — включая типичные подводные камни, связанные с порядком шаблонов и типами возвращаемых значений.
Когда использовать
Используйте preg_replace_callback_array(), когда:
- Нужно применить разную логику замены к разным шаблонам за один проход по тексту.
- В противном случае пришлось бы цепочить несколько вызовов
preg_replace_callback()— объединение их в один делает код читаемым и сохраняет намерение в одном месте. - Значение замены нельзя выразить статической строкой, поэтому обычный
preg_replace()не подходит — его нужно вычислять из найденного текста.
Если шаблон всего один, используйте preg_replace_callback(). Если замены представляют собой фиксированные строки — используйте preg_replace().
Синтаксис
preg_replace_callback_array(
array $pattern_and_callbacks,
string|array $subject,
int $limit = -1,
int &$count = null,
int $flags = 0
): string|array|null| Параметр | Описание |
|---|---|
$pattern_and_callbacks | Ассоциативный массив, ключи которого — шаблоны regex, а значения — callback-функции. Каждый callback получает массив совпадений и возвращает строку замены. |
$subject | Строка (или массив строк) для поиска и изменения. |
$limit | Максимальное количество замен на шаблон для каждой строки субъекта. По умолчанию -1 означает отсутствие ограничений. |
&$count | Если передан, заполняется общим количеством выполненных замен (по ссылке). |
$flags | Необязательные флаги PREG_OFFSET_CAPTURE и/или PREG_UNMATCHED_AS_NULL, изменяющие структуру $matches, передаваемой каждому callback. |
Возвращаемое значение: если $subject — строка, возвращается строка; если $subject — массив, возвращается массив. При ошибке регулярного выражения возвращает null.
Примечание: callback-функции должны возвращать строку. Числовое возвращаемое значение (например, int) автоматически приводится к строке. Возврат null приводит к пустой строке.
Базовый пример
Первый callback переводит каждое слово в верхний регистр; второй увеличивает каждую последовательность цифр на единицу. Оба шаблона применяются к одному тексту за один вызов.
<?php
$patterns_and_callbacks = [
'/[a-z]+/i' => function ($matches) {
return strtoupper($matches[0]);
},
'/\d+/' => function ($matches) {
return (int) $matches[0] + 1;
},
];
$string = 'This is a test string with 1234';
echo preg_replace_callback_array($patterns_and_callbacks, $string);
// THIS IS A TEST STRING WITH 1235Здесь $matches[0] — это полный текст, совпавший с шаблоном. Второй callback возвращает целое число (1234 + 1), которое PHP приводит к строке "1235".
Порядок шаблонов имеет значение
Шаблоны применяются в порядке элементов массива, и каждый следующий работает с результатом предыдущего. Это значит, что более ранний callback может изменить текст, который увидит более поздний шаблон — распространённый источник неожиданностей.
<?php
$subject = 'abc123';
$result = preg_replace_callback_array([
// Runs first: wraps every digit run in brackets.
'/\d+/' => fn ($m) => '[' . $m[0] . ']',
// Runs second: now sees "abc[123]" and upper-cases the letters.
'/[a-z]+/' => fn ($m) => strtoupper($m[0]),
], $subject);
echo $result;
// ABC[123]Если поменять местами два шаблона, буквы будут переведены в верхний регистр до применения шаблона цифр — результат для цифр тот же, но в общем случае порядок может изменить вывод.
Подсчёт замен с помощью $count
Передайте переменную четвёртым аргументом, чтобы узнать, сколько замен было выполнено по всем шаблонам.
<?php
$subject = 'cat dog cat bird cat';
$result = preg_replace_callback_array(
['/cat/' => fn ($m) => 'fish'],
$subject,
-1,
$count
);
echo $result . "\n"; // fish dog fish bird fish
echo "Replacements: $count"; // Replacements: 3Работа с массивом субъектов
Когда $subject — массив, функция обрабатывает каждый элемент и возвращает массив той же структуры.
<?php
$subjects = ['Order #12', 'Order #7'];
$result = preg_replace_callback_array(
['/\d+/' => fn ($m) => str_pad($m[0], 4, '0', STR_PAD_LEFT)],
$subjects
);
print_r($result);
// Array
// (
// [0] => Order #0012
// [1] => Order #0007
// )Распространённые ошибки
- Забытые разделители. Ключи должны быть корректными строками regex с разделителями, например
'/\d+/', а не'\d+'. Отсутствующий разделитель заставит вызов вернутьnullи выдать предупреждение. - Намеренный возврат не-строк. Хотя числовые значения приводятся автоматически, возврат массивов или объектов вызывает
TypeError. Приводите или форматируйте значение перед возвратом. - Предположение о независимости шаблонов. Как показано выше, каждый шаблон работает с результатом предыдущего. Составляйте массив обдуманно.
- Смешение полного совпадения и групп захвата.
$matches[0]— это всё совпадение;$matches[1],$matches[2], … — захваченные группы. Используйте правильный индекс в своей логике.
Связанные функции
preg_replace_callback()— один шаблон + один callback.preg_replace()— замена статическими строками или обратными ссылками.preg_match()иpreg_match_all()— поиск совпадений без замены.- PHP callback functions — как работают callable в PHP.
Заключение
preg_replace_callback_array() обеспечивает чистый однопроходный способ применения различной логики замены к нескольким шаблонам regex. Функция особенно полезна, когда каждый шаблон требует собственной вычисляемой замены, заменяя цепочку вызовов preg_replace_callback(). Помните, что шаблоны выполняются в порядке массива и что callback-функции должны возвращать строки — и функция сохранит ваш код преобразования текста компактным и читаемым.