Preg filter: примеры (PHP)
preg_filter(string|array $pattern, string|array $replacement, string|array $subject, int $limit = -1, int &$count = null): string|array|nullФункция 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 - переменная, в которую записывается количество произведенных замен
$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
)
$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
Основная альтернатива, которая всегда возвращает результат, даже если замен не было. preg_filter возвращает только измененные элементы, тогда как preg_replace оставляет неизмененные элементы на своих местах.
Используется, когда для замены требуется сложная логика, реализуемая через callback-функцию. Позволяет выполнять произвольные операции над найденными совпадениями.
Применяются для поиска без замены. preg_match_all особенно полезен при извлечении всех совпадений с возможностью получения дополнительной информации о позициях.
Используются для простых замен без регулярных выражений. Работают значительно быстрее при замене фиксированных строк.
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.
let text = 'JS ES6 и JS ES2022';
let result = text.replace(/JS/g, 'TypeScript');
console.log(result);TypeScript ES6 и TypeScript ES2022
SELECT REGEXP_REPLACE('MySQL 8.0 и MySQL 5.7', 'MySQL', 'MariaDB');MariaDB 8.0 и MariaDB 5.7
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 8.0 была изменена обработка недопустимых шаблонов регулярных выражений. Вместо генерации предупреждений теперь выбрасывается исключение типа ValueError.
Добавлена поддержка escape-последовательности \k для указания именованных захватывающих групп. Также улучшена обработка модификаторов регулярных выражений.
В этой версии был добавлен параметр $count, позволяющий получить количество выполненных замен. Ранее эта возможность отсутствовала.
$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
)
)
$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
$text = 'a1 b2 c3 d4 e5 f6';
$result = preg_filter('/\d/', '*', $text, 3);
echo $result;a* b* c* d4 e5 f6
// Пример реализации похожей логики с 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)
)
$text = 'Привет мир! Hello world! 12345';
$result = preg_filter('/[а-яё]+/ui', '[кириллица]', $text);
echo $result;[кириллица] мир! Hello world! 12345