Preg filter: примеры (PHP)

preg_filter: эффективная фильтрация данных через регулярные выражения
Раздел: Регулярные выражения
preg_filter(string|array $pattern, string|array $replacement, string|array $subject, int $limit = -1, int &$count = null): string|array|null
Основы функции preg_filter

Функция preg_filter() в PHP предназначена для выполнения поиска и замены по регулярному выражению. Главное отличие от схожей функции preg_replace заключается в том, что preg_filter возвращает только те элементы, в которых было найдено совпадение. Если совпадений нет, функция может вернуть пустой массив или null в зависимости от типа переданных данных.

Когда используется функция

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

Аргументы функции

Сигнатура функции: preg_filter(mixed $pattern, mixed $replacement, mixed $subject, int $limit = -1, int &$count = null): mixed

  • $pattern - строка или массив строк с регулярными выражениями
  • $replacement - строка или массив строк для замены найденных совпадений
  • $subject - строка или массив строк, в которых производится поиск
  • $limit - максимальное количество замен для каждого шаблона в каждой строке (по умолчанию -1 - без ограничений)
  • $count - переменная, в которую записывается количество произведенных замен
Примеры использования preg_filter
Простая замена в строке
$text = 'PHP 8.2 и PHP 7.4';
$result = preg_filter('/PHP/', 'JavaScript', $text);
echo $result;
JavaScript 8.2 и JavaScript 7.4
Фильтрация массива с заменой
$items = ['apple123', 'banana', 'cherry456', 'date'];
$result = preg_filter('/\d+/', '', $items);
print_r($result);
Array
(
[0] => apple
[2] => cherry
)
Использование флага PREG_OFFSET_CAPTURE
$text = 'test123 test456';
$result = preg_filter('/test(\d+)/', 'number', $text, -1, $count, PREG_OFFSET_CAPTURE);
echo $result . ' | Замен: ' . $count;
number number | Замен: 2
Работа с несколькими шаблонами
$text = 'foo123 bar456 baz';
$patterns = ['/foo/', '/bar/'];
$replacements = ['FOO', 'BAR'];
$result = preg_filter($patterns, $replacements, $text);
echo $result;
FOO123 BAR456 baz
Альтернативные функции в PHP

Основная альтернатива, которая всегда возвращает результат, даже если замен не было. preg_filter возвращает только измененные элементы, тогда как preg_replace оставляет неизмененные элементы на своих местах.

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

preg_match() и preg_match_all()

Применяются для поиска без замены. preg_match_all особенно полезен при извлечении всех совпадений с возможностью получения дополнительной информации о позициях.

str_replace() и str_ireplace()

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

Аналоги в других языках
Python: re.sub()
import re
text = 'Python 3.10 и Python 3.9'
result = re.sub(r'Python', 'Java', text)
print(result)
Java 3.10 и Java 3.9

Python не имеет прямой аналогии preg_filter, но можно создать похожее поведение с помощью filter() и lambda.

JavaScript: String.prototype.replace()
let text = 'JS ES6 и JS ES2022';
let result = text.replace(/JS/g, 'TypeScript');
console.log(result);
TypeScript ES6 и TypeScript ES2022
MySQL: REGEXP_REPLACE()
SELECT REGEXP_REPLACE('MySQL 8.0 и MySQL 5.7', 'MySQL', 'MariaDB');
MariaDB 8.0 и MariaDB 5.7
Go: regexp.ReplaceAllString()
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`Go`)
result := re.ReplaceAllString("Go 1.19 и Go 1.18", "Rust")
fmt.Println(result)
}
Rust 1.19 и Rust 1.18
Типичные ошибки
Неправильные разделители в шаблоне
// Отсутствует закрывающий разделитель
$result = preg_filter('/pattern', 'replace', 'test');
var_dump($result);
Warning: preg_filter(): Delimiter must not be alphanumeric or backslash
Ошибки в синтаксисе регулярных выражений
// Незакрытая квадратная скобка
$result = preg_filter('/[a-z/', '', 'test123');
var_dump($result);
Warning: preg_filter(): Compilation failed: missing terminating ] for character class
Несоответствие количества шаблонов и замен
$text = 'test string';
$patterns = ['/test/', '/string/'];
$replacements = ['only_one'];
$result = preg_filter($patterns, $replacements, $text);
var_dump($result);
NULL
Обращение к несуществующим группам замены
// В шаблоне нет групп захвата
$result = preg_filter('/\d+/', '$1', 'test123');
echo $result;
$1
Изменения в последних версиях PHP
PHP 8.0

В PHP 8.0 была изменена обработка недопустимых шаблонов регулярных выражений. Вместо генерации предупреждений теперь выбрасывается исключение типа ValueError.

PHP 7.3

Добавлена поддержка escape-последовательности \k для указания именованных захватывающих групп. Также улучшена обработка модификаторов регулярных выражений.

PHP 5.4

В этой версии был добавлен параметр $count, позволяющий получить количество выполненных замен. Ранее эта возможность отсутствовала.

Расширенные примеры
Обработка многоуровневого массива
Пример php
$data = [
'user1' => 'john@example.com',
'user2' => 'jane@test.org',
'meta' => ['admin@company.com', 'support@domain.net']
];

$result = preg_filter('/@(.*?)\./', '@newdomain.', $data);
print_r($result);
Array
(
[user1] => john@newdomain.com
[user2] => jane@newdomain.org
[meta] => Array
(
[0] => admin@newdomain.com
[1] => support@newdomain.net
)

)
Использование обратных ссылок с именованными группами
Пример php
$text = 'Date: 2023-12-25, Time: 14:30:45';
$pattern = '/(?P\d{4})-(?P\d{2})-(?P\d{2})/';
$replacement = '${day}.${month}.${year}';
$result = preg_filter($pattern, $replacement, $text);
echo $result;
Date: 25.12.2023, Time: 14:30:45
Фильтрация с ограничением количества замен
Пример php
$text = 'a1 b2 c3 d4 e5 f6';
$result = preg_filter('/\d/', '*', $text, 3);
echo $result;
a* b* c* d4 e5 f6
Комплексная обработка с callback-функцией через preg_replace_callback
Пример php
// Пример реализации похожей логики с preg_replace_callback
$data = ['temp_1', 'temp_2', 'humidity', 'pressure_3'];
$result = array_filter(
$data,
function($item) {
return preg_match('/_\d+$/', $item);
}
);
$result = preg_replace('/_(\d+)/', ' (номер: $1)', $result);
print_r($result);
Array
(
[0] => temp (номер: 1)
[1] => temp (номер: 2)
[3] => pressure (номер: 3)
)
Обработка UTF-8 строк с модификатором u
Пример php
$text = 'Привет мир! Hello world! 12345';
$result = preg_filter('/[а-яё]+/ui', '[кириллица]', $text);
echo $result;
[кириллица] мир! Hello world! 12345

PHP preg_filter function comments

En
Preg filter Perform a regular expression search and replace