preg_grep()
Функция preg_grep() в PHP фильтрует массив, оставляя элементы, совпадающие с регулярным выражением. Узнайте о синтаксе, флагах и примерах.
Введение
preg_grep() фильтрует массив, оставляя только те элементы, которые совпадают (или, опционально, не совпадают) с регулярным выражением. Это массиво-ориентированный член семейства PCRE в PHP: вместо проверки одной строки, как preg_match(), он перебирает каждый элемент массива и возвращает новый массив из элементов, прошедших проверку.
На этой странице рассматриваются сигнатура и параметры функции, разница между прямым и инвертированным совпадением, поведение ключей в возвращаемом массиве, распространённые практические применения и подводные камни.
Синтаксис
preg_grep(string $pattern, array $array, int $flags = 0): array|falseФункция принимает три параметра:
$pattern— паттерн PCRE, записанный в виде строки с разделителями (например,/^g/,~\d+~,#error#i).$array— входной массив для фильтрации. Проверяются только его значения, но не ключи.$flags(необязательный) — передайте константуPREG_GREP_INVERT, чтобы вернуть элементы, которые не совпадают. По умолчанию равен0(возвращает совпавшие элементы).
Функция возвращает новый массив, содержащий совпавшие элементы, сохраняя исходные ключи. Если паттерн невалидный, возвращает false и выдаёт предупреждение.
Базовый пример
preg_grep() перебирает массив и оставляет каждое значение, совпадающее с паттерном. Здесь мы оставляем только цвета, начинающиеся с буквы g:
Вывод:
Array
(
[2] => green
)Обратите внимание на ключ: green находилось по индексу 2 во входном массиве, и preg_grep() сохраняет этот ключ в результате. Возвращаемый массив, таким образом, не переиндексируется — если вам нужны последовательные ключи, оберните вызов в array_values().
Фильтрация с PREG_GREP_INVERT
Передайте PREG_GREP_INVERT в качестве третьего аргумента, чтобы инвертировать логику: вы получите обратно элементы, которые не прошли проверку паттерном. Это удобно для задач «убрать плохие записи». Здесь мы удаляем каждую строку, содержащую цифру:
<?php
$entries = ["apple1", "banana", "cherry7", "date", "fig2"];
$result = preg_grep("/[0-9]/", $entries, PREG_GREP_INVERT);
print_r($result);Вывод:
Array
(
[1] => banana
[3] => date
)Выживают только banana и date, потому что они не содержат цифр — и снова их исходные ключи (1 и 3) сохраняются.
Практические случаи применения
Фильтрация строк лога по уровню
Частая задача — извлечь только строки с ошибками из списка записей журнала. Чувствительный к регистру паттерн с якорем делает это точно:
<?php
$logs = [
"INFO ok",
"ERROR disk full",
"WARN low mem",
"ERROR timeout",
];
$errors = preg_grep("/^ERROR/", $logs);
print_r($errors);Вывод:
Array
(
[1] => ERROR disk full
[3] => ERROR timeout
)Оставить только полностью числовые строки
При валидации смешанных данных preg_grep() позволяет оставить только значения, соответствующие строгому шаблону, в одну строку. Якоря ^\d+$ гарантируют, что вся строка состоит из цифр:
<?php
$mixed = ["12", "ab", "3x", "99"];
$nums = preg_grep("/^\d+$/", $mixed);
print_r($nums);Вывод:
Array
(
[0] => 12
[3] => 99
)Подводные камни и советы
- Ключи сохраняются, а не сбрасываются. Как показано выше, пропуски в ключах результата — это нормально. Используйте
array_values(), если вам нужны0, 1, 2, …. - Проверяются только значения.
preg_grep()полностью игнорирует ключи массива — варианта на основе ключей не существует. - Невалидные паттерны возвращают
false, а не пустой массив. Всегда проверяйте тип результата, если паттерн поступает из пользовательского ввода:if ($result === false) { /* bad pattern */ }. - Функция не изменяет входной массив. Как большинство вспомогательных функций PHP для работы с массивами, она возвращает новый массив, оставляя
$arrayнетронутым. - Нестроковые значения приводятся к строке. Числа и другие скалярные значения преобразуются в строки перед совпадением, поэтому
preg_grep("/^1/", [10, 20])найдёт совпадение с10.
Связанные функции
preg_match()— проверить одну строку по паттерну.preg_match_all()— найти все совпадения в одной строке.preg_replace()— поиск и замена с использованием паттерна.preg_split()— разбить строку на массив по паттерну.preg_filter()— какpreg_replace(), но возвращает только совпавшие строки.
Заключение
preg_grep() — самый чистый способ фильтровать массив по регулярному выражению в PHP. Используйте её самостоятельно, чтобы оставить совпавшие элементы, добавьте PREG_GREP_INVERT, чтобы их убрать, и помните, что функция сохраняет исходные ключи. Для проверки одной строки используйте preg_match(); для замены — preg_replace().