Preg replace callback array: примеры (PHP)

Использование preg_replace_callback_array с примерами
Раздел: Регулярные выражения
preg_replace_callback_array(array $pattern, string|array $subject, int $limit = -1, int &$count = null, int $flags = 0): string|array|null
Функция preg_replace_callback_array в PHP

Функция preg_replace_callback_array выполняет поиск и замену в строке с использованием регулярных выражений, где для каждого шаблона можно указать отдельную callback-функцию. Она полезна, когда разные части текста требуют различной обработки.

Когда применяется

Использование актуально при необходимости применения нескольких замен с разной логикой обработки в одной операции. Типичные сценарии включают сложную обработку текста, преобразование разметки или санитизацию данных.

Аргументы функции
  • patterns — ассоциативный массив, где ключи являются шаблонами регулярных выражений, а значения — callback-функциями для обработки совпадений.
  • subject — строка или массив строк, в которых выполняется поиск и замена.
  • limit (необязательный) — максимальное количество замен для каждого шаблона. Значение -1 означает отсутствие ограничений.
  • count (необязательный) — переменная, в которую записывается общее количество выполненных замен.
  • flags (необязательный) — комбинация флагов: PREG_OFFSET_CAPTURE, PREG_UNMATCHED_AS_NULL. Влияет на формат передачи данных в callback-функцию.
Простые примеры использования
Базовая замена
$text = 'число 5 и число 10';
$result = preg_replace_callback_array([
    '/\\d+/' => function($matches) {
        return $matches[0] * 2;
    }
], $text);
echo $result;
число 10 и число 20
Использование нескольких шаблонов
$text = 'PHP 8 и JavaScript ES6';
$result = preg_replace_callback_array([
    '/PHP/' => function($m) { return 'Язык ' . $m[0]; },
    '/JavaScript/' => function($m) { return 'Скрипт ' . $m[0]; }
], $text);
echo $result;
Язык PHP 8 и Скрипт JavaScript ES6
Применение флага PREG_OFFSET_CAPTURE
$text = 'abc 123';
$result = preg_replace_callback_array([
    '/[a-z]+/' => function($m) {
        return strtoupper($m[0]);
    }
], $text, -1, $count, PREG_OFFSET_CAPTURE);
echo "Результат: $result, замен: $count";
Результат: ABC 123, замен: 1
Похожие функции в PHP
  • preg_replace_callback — выполняет замену по одному шаблону с callback-функцией. Подходит для однотипных замен.
  • preg_replace — выполняет замену без callback-функции, используя строки или массивы для замены. Эффективна для простых замен.
  • preg_match_all с последующей обработкой — позволяет захватывать совпадения и обрабатывать их произвольным образом, но требует больше кода.

Функцию preg_replace_callback_array предпочтительнее использовать при необходимости обработки разных шаблонов разными способами в одной операции, что улучшает читаемость и производительность по сравнению с последовательными вызовами других функций.

Типичные ошибки
Некорректный формат массива
// Ошибка: значение не является callable
$result = preg_replace_callback_array([
    '/\\d+/' => 'не_функция'
], 'текст');
// Вызовет TypeError
Использование неверного синтаксиса регулярных выражений
// Ошибка: незакрытая скобка
$result = preg_replace_callback_array([
    '/\\d(+/' => function($m) { return ''; }
], 'текст');
// Вернет NULL и вызовет предупреждение
Модификация исходной строки в callback
$text = 'число 5';
$ref = &$text;
$result = preg_replace_callback_array([
    '/\\d+/' => function($m) use (&$ref) {
        $ref = 'изменено'; // Опасная операция
        return $m[0];
    }
], $text);
// Поведение может быть непредсказуемым
Изменения в версиях PHP
  • PHP 7.0 — добавлена функция preg_replace_callback_array.
  • PHP 7.4 — добавлена поддержка флага PREG_UNMATCHED_AS_NULL.
  • PHP 8.0 — параметр flags стал необязательным. Улучшены сообщения об ошибках при некорректных шаблонах.
Расширенные примеры
Обработка различных типов данных в тексте
Пример php
$text = 'Цена: 100 руб, скидка 15%, код A1B2';
$result = preg_replace_callback_array([
    '/\\b\\d+\\b/' => function($m) { // числа
        return '[' . $m[0] . ']';
    },
    '/\\b\\d+%/' => function($m) { // проценты
        $num = rtrim($m[0], '%');
        return 'процент ' . $num;
    },
    '/[A-Z][0-9A-Z]+/' => function($m) { // коды
        return strtolower($m[0]);
    }
], $text);
echo $result;
Цена: [100] руб, скидка процент 15, код a1b2
Использование с limit
Пример php
$text = 'a1 a2 a3 a4 a5';
$result = preg_replace_callback_array([
    '/a\\d/'=> function($m) { return '[' . $m[0] . ']'; }
], $text, 2);
echo $result; // ограничение замен
[a1] [a2] a3 a4 a5
Комплексная обработка HTML
Пример php
$html = '<div>Текст <b>жирный</b> и <i>курсив</i></div>';
$result = preg_replace_callback_array([
    '/<b>(.*?)<\/b>/' => function($m) {
        return '<strong>' . strtoupper($m[1]) . '</strong>';
    },
    '/<i>(.*?)<\/i>/' => function($m) {
        return '<em>' . strtolower($m[1]) . '</em>';
    }
], $html);
echo htmlspecialchars($result);
<div>Текст <strong>ЖИРНЫЙ</strong> и <em>курсив</em></div>
Аналоги в других языках
Python: использование словаря с функциями
import re
text = 'число 5 и число 10'
def double(match):
    return str(int(match.group()) * 2)
def triple(match):
    return str(int(match.group()) * 3)
patterns = {
    r'\\d+': double
}
result = re.sub(r'\\d+', lambda m: patterns[r'\\d+'](m), text)
print(result)  # число 10 и число 20
число 10 и число 20
JavaScript: замена с использованием объекта функций
let text = 'PHP 8 и JavaScript ES6';
let patterns = {
    'PHP': (match) => 'Язык ' + match,
    'JavaScript': (match) => 'Скрипт ' + match
};
let result = text.replace(/PHP|JavaScript/g, match => patterns[match](match));
console.log(result);
Язык PHP 8 и Скрипт JavaScript ES6
MySQL: отсутствие прямой замены

В MySQL нет прямой аналогии. Простые замены выполняются функцией REGEXP_REPLACE, но сложная обработка требует создания пользовательских функций или обработки вне БД.

PHP preg_replace_callback_array function comments

En
Preg replace callback array Perform a regular expression search and replace using callbacks