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

Использование preg_match для поиска шаблонов в строках
Раздел: Регулярные выражения
preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int|false
Описание функции preg_match

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

Синтаксис и аргументы
preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int|false

$pattern - строка с регулярным выражением. Должна включать разделители, например, /шаблон/.

$subject - строка, в которой выполняется поиск.

$matches - массив для сохранения найденных совпадений. Первый элемент содержит полное совпадение, последующие - подмаски.

$flags - флаги изменения поведения функции:

  • PREG_OFFSET_CAPTURE - возвращает смещение для каждого найденного элемента
  • PREG_UNMATCHED_AS_NULL - несовпадающие подмаски возвращаются как NULL

$offset - позиция в строке, с которой начинается поиск (в байтах).

Функция возвращает 1 при нахождении совпадения, 0 при отсутствии и false при возникновении ошибки.

Базовые примеры использования
Проверка формата email
$email = "user@example.com";
$pattern = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';
$result = preg_match($pattern, $email);
echo $result;
1
Извлечение чисел из строки
$text = "Цена 1500 рублей";
$pattern = '/\d+/';
preg_match($pattern, $text, $matches);
print_r($matches);
Array
(
    [0] => 1500
)
Использование флага PREG_OFFSET_CAPTURE
$text = "test123";
$pattern = '/\d+/';
preg_match($pattern, $text, $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
Array
(
    [0] => Array
        (
            [0] => 123
            [1] => 4
        )
)
Поиск с указанием смещения
$text = "abc123def456";
$pattern = '/\d+/';
preg_match($pattern, $text, $matches, 0, 6);
print_r($matches);
Array
(
    [0] => 456
)
Похожие функции в PHP

Выполняет глобальный поиск шаблона в строке. Возвращает количество найденных совпадений. Подходит для извлечения всех вхождений.

Выполняет поиск и замену по регулярному выражению. Используется для модификации строк.

Аналогична preg_replace, но возвращает результат только если были замены.

Разделяет строку по регулярному выражению. Полезно для сложного разделения строк.

Когда что использовать

preg_match - для проверки наличия шаблона и извлечения первого совпадения.

preg_match_all - когда нужно получить все совпадения.

preg_replace - для замены найденных фрагментов.

preg_split - для разделения строк по сложным правилам.

Аналоги в других языках

Preg match в Python

import re
text = "Цена 1500 рублей"
result = re.search(r'\d+', text)
if result:
    print(result.group())
1500

В Python используется модуль re. Метод search ищет первое совпадение. Отличие - объект результата содержит больше информации.

Preg match в Javascript

let text = "Цена 1500 рублей";
let pattern = /\d+/;
let result = text.match(pattern);
console.log(result[0]);
1500

В JavaScript метод match строкового объекта возвращает массив совпадений. Флаги указываются в конце регулярного выражения.

Preg match в MySQL

SELECT 'Цена 1500 рублей' REGEXP '[0-9]+' as result;
1

MySQL использует оператор REGEXP для проверки соответствия. Возвращает 1 при совпадении, 0 при отсутствии.

Типичные ошибки
Отсутствие разделителей в шаблоне
$text = "test";
$pattern = 'test'; // Нет разделителей
$result = preg_match($pattern, $text);
var_dump($result);
bool(false)
Некорректные модификаторы
$text = "test";
$pattern = '/test/z'; // Несуществующий модификатор 'z'
$result = preg_match($pattern, $text);
var_dump($result);
bool(false)
Попытка использовать несуществующий индекс массива
$text = "test";
$pattern = '/\d+/';
preg_match($pattern, $text, $matches);
echo $matches[0]; // Совпадений нет, массив может быть пустым
PHP Notice:  Undefined offset: 0
Неправильная обработка кириллицы
$text = "Привет";
$pattern = '/[А-Яа-я]+/';
preg_match($pattern, $text, $matches); // Без модификатора u
print_r($matches);
Array
(
    [0] => П
)

Для корректной работы с UTF-8 нужно добавлять модификатор u: /[А-Яа-я]+/u

Изменения в новых версиях PHP
PHP 7.0

Добавлена поддержка флага PREG_JIT_SUPPORT для JIT-компиляции регулярных выражений.

PHP 7.2

Константа PREG_UNMATCHED_AS_NULL стала доступна. Несовпадающие подмаски теперь могут возвращаться как NULL.

PHP 8.0

При передаче null в параметр $subject теперь возникает TypeError. Ранее это интерпретировалось как пустая строка.

// PHP 7.4 и ранее
preg_match('/test/', null); // Возвращало false

// PHP 8.0+
preg_match('/test/', null); // TypeError

Улучшена производительность и обработка ошибок.

Расширенные примеры
Именованные группы
Пример php
$text = "Дата: 2023-12-31";
$pattern = '/(?P\d{4})-(?P\d{2})-(?P\d{2})/';
preg_match($pattern, $text, $matches);
print_r($matches);
Array
(
    [0] => 2023-12-31
    [year] => 2023
    [1] => 2023
    [month] => 12
    [2] => 12
    [day] => 31
    [3] => 31
)
Условные подмаски
Пример php
$texts = ["https://example.com", "http://example.com", "ftp://example.com"];
$pattern = '/^(https?|ftp):\/\/([^\/\s]+)/';

foreach ($texts as $text) {
    preg_match($pattern, $text, $matches);
    echo "Протокол: {$matches[1]}, Домен: {$matches[2]}\n";
}
Протокол: https, Домен: example.com
Протокол: http, Домен: example.com
Протокол: ftp, Домен: example.com
Рекурсивные шаблоны
Пример php
$text = "Вложенные (скобки (внутри) других) скобок";
$pattern = '/\(([^()]|\((?1)\))*\)/';
preg_match($pattern, $text, $matches);
echo $matches[0];
(скобки (внутри) других)
Проверка сложного пароля
Пример php
function checkPassword($password) {
    // Минимум 8 символов, заглавные, строчные, цифры и спецсимволы
    $pattern = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/';
    return preg_match($pattern, $password) === 1;
}

$passwords = ["Weak1", "StrongPass1!", "NoSpecialChar1"];
foreach ($passwords as $pwd) {
    echo "$pwd: " . (checkPassword($pwd) ? "OK" : "Неверно") . "\n";
}
Weak1: Неверно
StrongPass1!: OK
NoSpecialChar1: Неверно
Извлечение данных из логов
Пример php
$log = "[2023-12-31 23:59:59] ERROR: Database connection failed at user=admin";
$pattern = '/\[(?P[^\]]+)\]\s+(?P\w+):\s+(?P.+?)(?:\s+at\s+(?P.+))?$/';
preg_match($pattern, $log, $matches, PREG_UNMATCHED_AS_NULL);

unset($matches[0], $matches[1], $matches[2], $matches[3], $matches[4]);
print_r($matches);
Array
(
    [datetime] => 2023-12-31 23:59:59
    [level] => ERROR
    [message] => Database connection failed
    [context] => user=admin
)

PHP preg_match function comments

En
Preg match Perform a regular expression match