preg_match_all

(PHP 4, PHP 5, PHP 7, PHP 8)

preg_match_allВыполняет глобальный поиск шаблона в строке

Описание

function preg_match_all(
    string $pattern,
    string $subject,
    array &$matches = null,
    int $flags = 0,
    int $offset = 0
): int|false

Функция ищет в строке subject все совпадения с шаблоном регулярного выражения pattern и помещает результат в массив matches в порядке, который определяет комбинация флагов flags.

После обнаружения первого соответствия поиски продолжаются с конца последнего совпадения.

Список параметров

pattern

Искомый шаблон в виде строки.

subject

Входная строка.

matches

Многомерный массив совпадений, сортировка которого соответствует параметру flags.

flags
Функция возьмёт флаг по умолчанию — PREG_PATTERN_ORDER, если флаг сортировки не передали.

Параметр принимает комбинацию следующих флагов (обратите внимание, указывать флаг PREG_PATTERN_ORDER одновременно с флагом PREG_SET_ORDER бессмысленно):

PREG_PATTERN_ORDER

Флаг упорядочивает результаты так, что элемент $matches[0] содержит массив полных вхождений шаблона, элемент $matches[1] содержит массив вхождений первого подшаблона в круглых скобках и т. д.

<?php

preg_match_all("|<[^>]+>(.*)</[^>]+>|U",
    "<b>Пример: </b><div align=left>это тест</div>",
    $out, PREG_PATTERN_ORDER);
echo $out[0][0] . ", " . $out[0][1] . "\n";
echo $out[1][0] . ", " . $out[1][1] . "\n";

?>

Результат выполнения приведённого примера:

<b>Пример: </b>, <div align=left>это тест</div>
пример: , это тест

Так, элемент $out[0] содержит массив строк, которые соответствуют полному шаблону, а элемент $out[1] содержит массив строк в тегах.

Массив $matches будет дополнительно содержать записи для ключей с именами подшаблонов, если шаблон содержит именованные подшаблоны.

Функция сохранит в элементе $matches[NAME] только самый правый подшаблон, если шаблон содержит повторяющиеся именованные подшаблоны.

<?php

preg_match_all(
    '/(?J)(?<match>foo)|(?<match>bar)/',
    'foo bar',
    $matches,
    PREG_PATTERN_ORDER
);
print_r($matches['match']);

?>

Результат выполнения приведённого примера:

Array
(
    [0] =>
    [1] => bar
)

PREG_SET_ORDER

Флаг упорядочивает результаты так, что элемент $matches[0] становится массивом с первым набором вхождений, а элемент $matches[1] — со вторым набором вхождений и т. д.

<?php

preg_match_all("|<[^>]+>(.*)</[^>]+>|U",
    "<b>пример: </b><div align=\"left\">это тест</div>",
    $out, PREG_SET_ORDER);
echo $out[0][0] . ", " . $out[0][1] . "\n";
echo $out[1][0] . ", " . $out[1][1] . "\n";

?>

Результат выполнения приведённого примера:

<b>пример: </b>, пример:
<div align="left">это тест</div>, это тест

PREG_OFFSET_CAPTURE

С этим флагом для каждой найденной подстроки функция также вернёт позицию подстроки в исходной строке (в байтах). Обратите внимание, что этот флаг изменяет массив matches на многомерный, каждый элемент которого содержит массив, который содержит в индексе с номером 0 найденную подстроку, а смещение этой подстроки в параметре subject — в индексе 1.

<?php

preg_match_all('/(foo)(bar)(baz)/', 'foobarbaz', $matches, PREG_OFFSET_CAPTURE);
print_r($matches);

?>

Результат выполнения приведённого примера:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => foobarbaz
                    [1] => 0
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [0] => foo
                    [1] => 0
                )

        )

    [2] => Array
        (
            [0] => Array
                (
                    [0] => bar
                    [1] => 3
                )

        )

    [3] => Array
        (
            [0] => Array
                (
                    [0] => baz
                    [1] => 6
                )

        )

)

PREG_UNMATCHED_AS_NULL

С этим флагом несовпадающие подмаски функция представит значениями null; иначе отобразит в виде пустых строк (string).

offset

Обычно поиск выполняется с начала строки слева направо. Через необязательный параметр offset указывают другую позицию (в байтах), с которой функция начнёт поиск.

Замечание:

Поведение параметра offset не эквивалентно замене сопоставляемой строки выражением substr($subject, $offset) при вызове функции preg_match_all(), поскольку шаблон pattern может содержать условия наподобие ^, $ или (?<=x). Примеры смотрите в описании функции preg_match().

Возвращаемые значения

Функция возвращает количество полных совпадений с шаблоном, включая 0, или false, если возникла ошибка.

Ошибки

Если передали шаблон регулярного выражения, который не компилируется в допустимое регулярное выражение, выдаётся ошибка уровня E_WARNING.

Список изменений

Версия Описание
7.2.0 Теперь параметр $flags поддерживает константу PREG_UNMATCHED_AS_NULL.

Примеры

Пример #1 Получение всех телефонных номеров из текста.

<?php

preg_match_all(
    "/\(?  (\d{3})?  \)?  (?(1)  [\-\s] ) \d{3}-\d{4}/x",
    "Звоните 555-1212 или 1-800-555-1212",
    $phones
);

?>

Пример #2 Жадный поиск совпадений с HTML-тэгами

<?php

// Запись \\2 — пример ссылки на подшаблон.
// Запись говорит инструкции Perl-совместимого регулярного выражения,
// что оно должно соответствовать набору, который захватили
// вторые круглые скобки в самом шаблоне, в примере это ([\w]+).
// Дополнительный обратный слеш требуется, потому что строка в двойных кавычках.
$html = "<b>полужирный текст</b><a href=howdy.html>нажми</a>";

preg_match_all("/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/", $html, $matches, PREG_SET_ORDER);

foreach ($matches as $val) {
    echo "совпадение: " . $val[0] . "\n";
    echo "часть 1: " . $val[1] . "\n";
    echo "часть 2: " . $val[2] . "\n";
    echo "часть 3: " . $val[3] . "\n";
    echo "часть 4: " . $val[4] . "\n\n";
}

?>

Результат выполнения приведённого примера:

совпадение: <b>полужирный текст</b>
часть 1: <b>
часть 2: b
часть 3: полужирный текст
часть 4: </b>

matched: <a href=howdy.html>нажми</a>
часть 1: <a href=howdy.html>
часть 2: a
часть 3: нажми
часть 4: </a>

Пример #3 Работа с именованными подшаблонами

<?php

$str = <<<FOO
a: 1
b: 2
c: 3
FOO;

preg_match_all('/(?P<name>\w+): (?P<digit>\d+)/', $str, $matches);

/* Альтернативный вариант */
// preg_match_all('/(?<name>\w+): (?<digit>\d+)/', $str, $matches);

print_r($matches);

?>

Результат выполнения приведённого примера:

Array
(
    [0] => Array
        (
            [0] => a: 1
            [1] => b: 2
            [2] => c: 3
        )

    [name] => Array
        (
            [0] => a
            [1] => b
            [2] => c
        )

    [1] => Array
        (
            [0] => a
            [1] => b
            [2] => c
        )

    [digit] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [2] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

)

Смотрите также

  • Регулярные выражения PCRE
  • preg_quote() - Экранирует символы в регулярных выражениях
  • preg_match() - Выполняет проверку на соответствие регулярному выражению
  • preg_replace() - Выполняет поиск и замену по регулярному выражению
  • preg_split() - Разбивает строку по регулярному выражению
  • preg_last_error() - Возвращает код ошибки выполнения последнего регулярного выражения PCRE