W3docs

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_array() обеспечивает чистый однопроходный способ применения различной логики замены к нескольким шаблонам regex. Функция особенно полезна, когда каждый шаблон требует собственной вычисляемой замены, заменяя цепочку вызовов preg_replace_callback(). Помните, что шаблоны выполняются в порядке массива и что callback-функции должны возвращать строки — и функция сохранит ваш код преобразования текста компактным и читаемым.

Практика

Практика
Что делает функция preg_replace_callback_array в PHP?
Что делает функция preg_replace_callback_array в PHP?
Was this page helpful?