yakoffka.ru
    грабли, костыли и велосипеды php, css, html, js и прочего

    Памятка по регулярным выражениям

    Регулярные выражения«Если столкнувшись с проблемой вы подумали, что решите ее при помощи регулярных выражений, то у вас две проблемы»

    Anonymous

    оглавление


    Регулярные выражения могут состоять из символов (обычных и специальных - метасимволов) и операций(квантификации, перечисления, группировки)

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

    Часто используемыми разделителями являются косые черты (/), знаки решетки (#) и тильды (~). Ниже представлены примеры шаблонов с корректными разделителями:

    '/this [is] a (pattern)/'
    '#this [is] a (pattern)#'
    '~this [is] a (pattern)~'

    Также можно использовать разделитель в виде скобок, где стартовый и завершающий разделители являются соответственно открывающей и закрывающей скобками. (), {}, [] и <> являются допустимыми парами разделителей. Если разделители в виде скобок используются в шаблонене как метасимволы, то экранировать их не требуется:

    '(this [is] a (pattern))'
    '{this [is] a (pattern)}'
    '[this [is] a (pattern)]'
    '<this [is] a (pattern)>'

    Но их нужно экранировать, как и другие разделители если они используются непосредственно как символы:

    '/https:\/\//'
    '#https://#'

    Если разделитель часто используется в шаблоне, то в целях удобочитаемости, лучше выбрать другой разделитель для этого шаблона.

    Метасимволы в отличие от обычных символов интерпретируются специальным образом.

    Существуют два различных набора метасимволов: те, которые используются внутри квадратных скобок, и те, которые используются вне квадратных скобок. Вне квадратных скобок используются следующие метасимволы:

    Метасимволы вне квадратных скобок
    Метасимвол Описание
    \ общий экранирующий символ, допускающий несколько вариантов применения. PHP-строки, заключенные в одинарные и двойные кавычки, интерпретируют обратную косую черту по-разному. Поэтому, если необходимо совпадение '\' с регулярным выражением '\\', в PHP-коде нужно использовать "\\\\" или '\\\\'.
    ^ декларирует начало данных (или строки в многострочном режиме)
    $ декларирует конец данных или до завершения строки (или окончание строки в многострочном режиме)
    . Вне символьного класса точка соответствует любому (в том числе и непечатному, бинарному) символу, кроме символа перевода строки '\n' (в обычном режиме). В случае, если используется модификатор PCRE_DOTALL, точка соответствует также символу перевода строки. Обработка метасимвола 'точка', никак не связана с метасимволами начала и конца строки, единственное, что у них общего - так это специальное отношение к символу перевода строки. Внутри символьного класса точка не имеет специального значения.
    Для совпадения с одним байтом можно использовать последовательность \C. Это может быть полезно в режиме UTF-8, так как с точкой в этом режиме будет совпадать целый символ, который может состоять из нескольких байт.
    [ начало описания символьного класса
    ] конец описания символьного класса
    | начало ветки условного выбора
    ( начало подмаски
    ) конец подмаски
    ? расширяет смысл метасимвола '(', является также квантификатором, означающим 0 или 1 вхождение, также преобразует жадные квантификаторы в ленивые.
    * квантификатор, означающий нуль или более вхождений
    + квантификатор, означающий одно или более вхождений
    { начало количественного квантификатора
    } конец количественного квантификатора

    Часть шаблона, заключенная в квадратные скобки называется символьным классом. В символьном классе используются следующие метасимволы:

    Метасимволы внутри квадратных скобок (в символьном классе)
    Метасимвол Описание
    \ общий экранирующий символ
    ^ означает отрицание класса, допустим только в начале класса
    - означает символьный интервал
    пример:
    паттерн строка результат
    ~c.t~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    Регулярное выражение с одним любым символом между символами 'c' и 't'.
    ~c.+t~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    Регулярное выражение с квантификатором '+' (одно или более вхождений любых символов).

    Для поиска символов, повторяющихся от N до M раз включительно используют квантификатор повторения: '{N,M}'.

    Квантификаторы распространяют своё действие на предшествующий им символ (включая экранированный символ, метасимвол '.'), символьным классом, ссылкой на предыдущий фрагмент шаблона либо взятой в круглый скобки подмаской (если это не утверждение).

    Существуют обычная '{N,M}', упрощенная ('{N,}', '{N}') и сокращенная ('?', '+', '*') формы записи квантификатора повторения:

    Сокращенная форма записи квантификатора повторения описывает три наиболее распространённых квантификатора.

    Формы записи квантификаторов
    квантификатор Аналог Описание
    {N,M} - поиск символов, повторяющихся от N до M раз включительно
    {N,} {N,∞} поиск символов, повторяющихся от N до бесконечности раз включительно
    {N} {N,N} поиск символов, повторяющихся N раз
    ? {0,1} поиск символов, повторяющихся от 0 до 1 раз включительно
    + {1,∞} поиск символов, повторяющихся от 1 раза до бесконечности
    * {0,∞} типа 'здесь может быть что-то еще, но не факт'

    Общий квантификатор повторения указывает минимальное и максимальное допустимое количество совпадений, согласно двум числам, заключенными в фигурные скобки и разделенными запятой. Числа должны быть меньше чем 65536, и первое число не должно превышать второе по значению. Например: z{2,4} соответствует 'zz', 'zzz' или 'zzzz'. Закрывающая фигурная скобка сама по себе не является специальным символом. В случае, если второе число опущено, но запятая присутствует, нет верхнего предела; в случае, если и второе число и запятая опущены, требуется точное число повторений. Таким образом [aeiou]{3,} соответствует как минимум трем последовательным гласным (а также любому их количеству выше трех), в то время как \d{8} соответствует ровно восьми цифрам. Открывающая фигурная скобка, расположенная в недопустимой для квантификатора позиции, либо не соответствующая синтаксису квантификатора, интерпретируется как обыкновенная символьная строка. Например, {,6} не является квантификатором, а интерпретируется как символьная строка из четырех символов.

    Квантификатор {0} является допустимым и ведет себя таким образом, будто бы сам квантификатор и предшествующий ему элемент отсутствуют.

    пример:
    паттерн строка результат
    ~a.{1,2}s~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    подстрока должна начинаться на символ 'a', затем должны следовать один или два почти любых символа и символ 's'.
    ~cat.*? ~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    Ищем 'cat' с окончанием и без, с последующим пробелом. В данном случае квантификатором является символ '*', а следующий за ним '?' уже становится метасимволом, преобразущим жадные квантификаторы в ленивые

    Символьный класс соответствует одиночному символу обрабатываемой строки, причем сам символ должен содержаться в наборе, определяемым классом.

    Открывающая квадратная скобка объявляет начало символьного класса, завершаемого закрывающей квадратной скобкой.

    Различают встроенные и пользовательские классы символов.

    Встроенные классы символов:

    Встроенные классы символов
    класс описание
    [\s] любой пробельный символ (пробел, табуляция, вертикальная(!) табуляция, переносы строк и тп).
    Класс символов не включает в себя неразрывный пробел (символ с Unicode-кодом 00A0). Так что в случае, когда необходимо его обрабатывать также, как остальные пробельные символы, приходится указывать его явно: '\u00A0' (?). В то-же время модификатор 'u' позволяет распознать неразрывный пробел как пробельный символ (!).
    [\S] любой непробельный символ.
    [\s\S] любой символ (теперь точно любой, это Вам не '.'!).
    [\d] десятичная цифра.
    [\D] любой символ, но не десятичная цифра.
    [\w] любой символ, образующий 'слово'.
    [\W] не цифра.

    Пользовательские классы символов также задаются перечислением в квадратных скобках, и такое перечисление соответствует ОДНОМУ символу из данного класса.

    Знаком '-' задается диапазон символов. Для включения в набор символа '-' необходимо установить его в такой позиции, в которой он не может интерпретироваться как диапазон (как правило, это первый и последний символ описания класса), либо заэкранировать при помощи обратного слеша.

    Пользовательские классы символов
    класс описание
    [a,b,c] символ 'a', либо 'b', либо 'c'.
    [a-d] любой символ из последовательности 'a-d'.
    [0-9] любая (арабская! десятичная!) цифра.
    [0-9-] любая (арабская! десятичная!) цифра и символ '-'.
    [^0-9] не цифра.

    Perl поддерживает нотацию POSIX для символьных классов. Это включает использование имен, заключенных в [: и :], в свою очередь заключенных в квадратные скобки. PCRE также поддерживает эту запись. Например, [01[:alpha:]%] совпадет с "0", "1", любым алфавитным символом или "%". Поддерживаются следующие имена классов:

    POSIX нотация для символьных классов
    alnum буквы и цифры
    alpha буквы
    ascii символы с кодами 0 - 127
    blank только пробел или символ табуляции
    cntrl управляющие символы
    digit десятичные цифры (то же самое, что и \d)
    graph печатные символы, исключая пробел
    lower строчные буквы
    print печатные символы, включая пробел
    punct печатные символы, исключая буквы и цифры
    space пробельные символы(почти то же самое, что и \s)
    upper прописные буквы
    word символы "слова" (то же самое, что и \w)
    xdigit шестнадцатеричные цифры
    пример:
    паттерн строка результат
    ~[\w]+~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    выбираем все слова.
    ~[\s]+[\w]{4}[\s]+~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    слово из 4-ёх символов, ограниченное пробельными символами.
    ~[c,d][a,o][t,g][s]~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    ищем подстроку, начинающуюся на 'c' или 'd', далее 'a' или 'o' и т.д.

    Символ ']' не имеет специального значения, и в случае, если закрывающая квадратная скобка необходима как член символьного класса, она должна быть первым символом непосредственно после открывающей квадратной скобки (если используется метасимвол '^', то непосредственно после него), либо экранироваться при помощи обратного слеша.

    Вообще все не буквенно-цифровые символы, кроме \, -, ^ (вначале) и завершающего ']', не являются специальными символами, но использование экранирующего слеша перед ними не навредит. Символ конца шаблона всегда является особым случаем и всегда должен быть проэкранирован внутри выражения.

    В случае, если первым символом описания класса является символ циркумфлекс'^', логика работы инвертируется: класс соответствует одиночному символу, который не содержится в наборе, определяемым классом. Если символ '^' необходим как член класса, его не следует помещать первым символом в описании класса либо необходимо экранировать при помощи обратного слеша.

    Символьные классы, построенные на отрицании, например [^a], всегда соответствуют символу перевода строки.

    пример:
    паттерн строка результат
    ~[a,c,i,n]{2}~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    подстрока должна включать в себя два символа из набора '[a,c,i,n]'.
    ~\[[a-z]+\]~u It cat r[ain]s cats [and] dogs in city. It cat r[ain]s cats [and] dogs in city.
    выбираем символы (не менее одного), заключенные в квадратные скобки.
    ~[^\]\[]~u It cat r[ain]s cats [and] dogs in city. It cat r[ain]s cats [and] dogs in city.
    выбираем все, кроме квадратных скобок.

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

    Модификаторы регулярных выражений
    модификатор описание
    A PCRE_ANCHORED Если используется данный модификатор, соответствие шаблону будет достигаться только в том случае, если он "заякорен", то есть соответствует началу строки, в которой производится поиск. Того же эффекта можно достичь подходящей конструкцией с вложенным шаблоном, которая является единственным способом реализации этого поведения в Perl.
    D PCRE_DOLLAR_ENDONLY Если используется данный модификатор, метасимвол $ в шаблоне соответствует только окончанию обрабатываемых данных. Без этого модификатора метасимвол $ соответствует также позиции перед последним символом, в случае, если им является перевод строки (но не распространяется на любые другие переводы строк). Данный модификатор игнорируется, если используется модификатор m. В языке Perl аналогичный модификатор отсутствует.
    U PCRE_UNGREEDY Этот модификатор инвертирует жадность квантификаторов, таким образом они по умолчанию не жадные. Но становятся жадными, если за ними следует символ '?'. Такая возможность не совместима с Perl. Его также можно установить с помощью '(?U)' установки модификатора внутри шаблона или добавив знак вопроса после квантификатора (например, '.*?').
    S В случае, если планируется многократно использовать шаблон, имеет смысл потратить немного больше времени на его анализ, чтобы уменьшить время его выполнения. В случае, если данный модификатор используется, проводится дополнительный анализ шаблона. В настоящем это имеет смысл только для "незаякоренных" шаблонов, не начинающихся с какого-либо определенного символа.
    X PCRE_EXTRA Этот модификатор включает дополнительную функциональность PCRE, которая не совместима с Perl: любой обратный слеш в шаблоне, за которым следует символ, не имеющий специального значения, приводят к ошибке. Это обусловлено тем, что подобные комбинации зарезервированы для дальнейшего развития. По умолчанию же, как и в Perl, слеш со следующим за ним символом без специального значения трактуется как опечатка. На сегодняшний день это все возможности, которые управляются данным модификатором.
    J PCRE_INFO_JCHANGED Модификатор (?J) меняет значение локальной опции PCRE_DUPNAMES - подшаблоны могут иметь одинаковые имена. Модификатор J поддерживается с версии PHP 7.2.0.
    i PCRE_CASELESS Делает регулярное выражение нечувствительным к регистру символов (символы в шаблоне соответствуют символам как верхнего, так и нижнего регистра.).
    m PCRE_MULTILINE multy-line. перевод выражения в многострочный режим. По умолчанию PCRE обрабатывает данные как однострочную символьную строку (даже если она содержит несколько разделителей строк). Метасимвол начала строки '^' соответствует только началу обрабатываемого текста, в то время как метасимвол "конец строки" '$' соответствует концу текста, либо позиции перед завершающим текст переводом строки (в случае, если модификатор D не установлен). В Perl ситуация полностью аналогична. Если этот модификатор используется, метасимволы "начало строки" и "конец строки" также соответствуют позициям перед произвольным символом перевода и строки и, соответственно, после, как и в самом начале и в самом конце строки. Это соответствует Perl-модификатору /m. В случае, если обрабатываемый текст не содержит символов перевода строки, либо шаблон не содержит метасимволов '^' или '$', данный модификатор не имеет никакого эффекта.
    s PCRE_DOTALL Если данный модификатор используется, метасимвол "точка" в шаблоне соответствует всем символам, включая перевод строк. Без него - все символы, кроме переводов строк. Этот модификатор эквивалентен записи /s в Perl. Класс символов, построенный на отрицании, например [^a], всегда соответствует переводу строки, независимо от наличия этого модификатора.
    x PCRE_EXTENDED Если используется данный модификатор, то неэкранированные пробелы, символы табуляции и пустой строки будут проигнорированы в шаблоне (если они не являются частью символьного класса). Также игнорируются все символы между неэкранированным символом '#' (если он не является частью символьного класса) и символом перевода строки (включая сами символы ' ' и '#'). Это эквивалентно Perl-модификатору /x, и позволяет размещать комментарий в сложных шаблонах. Замечание: это касается только символьных данных. Пробельные символы не фигурируют в служебных символьных последовательностях, к примеру, в последовательности '(?(', открывающей условную подмаску.
    e PREG_replacement_EVAL Эта функциональность считается УСТАРЕВШЕЙ с PHP 5.5.0, и УДАЛЕНА в PHP 7.0.0. Использовать этот модификатор не рекомендуется, так как это может легко добавить уязвимости в системе безопасности.
    u Заставляет регулярное выражение понимать юникод. Этот модификатор включает дополнительную функциональность PCRE, которая не совместима с Perl: шаблон и целевая строка обрабатываются как UTF-8 строки. Недопустимая целевая строка приводит к тому, что функции preg_* ничего не находят, а неправильный шаблон приводит к ошибке уровня E_WARNING. Пятый и шестой октеты UTF-8 последовательности рассматриваются недопустимыми с PHP 5.3.4 (согласно PCRE 7.3 2007-08-28); ранее они считались допустимыми. Применять по назначению врача!
    пример:
    паттерн строка результат
    ~i.~i It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    подстрока должна включать в себя два символа: 'i' и еще один почти любой ('.'). Модификатором 'i' присваиваем паттерну регистронезависимость.
    ~i.#комментарий#~ix It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    добавляем комментарий при помощи модификатора 'x'.

    Якорь задает позицию символа в строке и не соответствует никакому символу. Специальная метка позиции, указывающая, где могут находиться символы.

    Поведение якорей может зависеть от однострочного либо многострочного режима.

    Якоря
    якорь описание
    ^ декларирует начало данных (или строки в многострочном режиме).
    $ декларирует конец данных или до завершения строки (или окончание строки в многострочном режиме).
    \b граница слова.
    \A начало данных (независимо от многостраничного режима). в однострочном режиме соответствует '^'.
    \Z конец данных (независимо от многостраничного режима). в однострочном режиме соответствует '$'.

    Метасимвол начала строки (^) не обязан быть первым символом шаблона в случае, если в шаблоне используются несколько альтернатив, но должен быть первым символом в каждой из альтернатив, в которой он встречается, если шаблон когда-либо сопоставим с соответствующей веткой. Если все альтернативы начинаются с метасимвола начала строки (^), то шаблон ограничен для совпадения исключительно в начале строки, говорят что шаблон 'заякорен'. (Существуют и другие способы 'заякорить' шаблон).

    Значение метасимволов начала и конца строки меняется в случае, если используется модификатор PCRE_MULTILINE. В таком случае, помимо совпадений в начале или в конце строки, метасимволы '^' и '$' соответствуют позиции непосредственно после символа перевода строки '\n'. Например, шаблон /^abc$/ встречается в строке 'def\nabc' в многострочном режиме и не встречается в нормальном режиме. Таким образом, шаблон который 'заякорен' в однострочном режиме, все ветки которого, начинаются с '^', не будет являться 'заякоренным' в многострочном режиме. Модификатор PCRE_DOLLAR_ENDONLY игнорируется в случае, если модификатор установлен PCRE_MULTILINE.

    пример:
    паттерн строка результат
    ~\b(\w)+\b~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    подстрока из символов, составляющих слово, ограниченная границами слова... слово, в общем-та.
    ~\b(\w)+\b\.\Z~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    слово, стоящая за ним точка и конец данных.
    ~^\b(\w)+\b~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    слово, стоящее в начале данных.

    Символ вертикальной черты '|' используется для разделения альтернативных масок. Например, шаблон (cat|dog|) соответствует как 'cat', так и 'dog'. Допустимо указывать любое количество альтернатив, также допустимо указывать пустые альтернативы (соответствуют пустой строке). В процессе поиска соответствия просматриваются все перечисленные альтернативы слева направо, останавливаясь после первого найденного соответствия. В случае, если альтернативные варианты перечислены в подмаске, то весь шаблон совпадет только в случае соответствия одного из альтернативных вариантов подмаски и остатка основного шаблона.

    пример:
    паттерн строка результат
    ~(cat|dog|)s~ It cat rains cats and dogs in city. It cat rains cats and dogs in city.
    подстрока содержащая символ 's' и предшествующие ей 'cat', 'dog' или ''.

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

    • Локализирует набор альтернатив. Например, шаблон cat(aract|erpillar|) соответствует одному из слов 'cat', 'cataract' или 'caterpillar'. Без использования скобок он соответствовал бы строкам 'cataract', 'erpillar' или пустой строке.
    • Указывает на необходимость захвата подстроки (как показано выше). В том случае, если соответствие шаблону было найдено, подстрока, соответствующая подмаске, также передается обратно вызывающему при помощи аргумента ovector функции pcre_exec(). Открывающие круглые скобки нумеруются слева направо (начиная с единицы) и их порядковые номера используются для нумерации соответствующих подстрок в результате.

    Например, если строка 'the red king' сопоставляется с шаблоном the ((red|white) (king|queen)), будут захвачены подстроки 'red king', 'red' и 'king', с номерами 1, 2 и 3 соответственно.

    В случае, когда необходима группировка альтернатив без захвата строки, после открывающей круглой скобки необходимо прописать '?:', и тогда захвата строки не происходит, а текущая подмаска не нумеруется. Например, если строка 'the white queen' сопоставляется с шаблоном the ((?:red|white) (king|queen)), будут захвачены подстроки 'white queen' и 'queen', и они будут пронумерованы 1 и 2 соответственно. Максимальное количество захватывающих подмасок - 65535. Такие большие шаблоны могут не скомпилироваться, в зависимости от настроек libpcre.

    В случае, если в незахватывающей подмаске необходимо указать дополнительные опции, можно воспользоваться удобным сокращением: символ, обозначающий устанавливаемую опцию помещается между '?' и ':'. Таким образом, следующие два шаблона

    '(?i:saturday|sunday)'
    '(?:(?i)saturday|sunday)'

    соответствуют одному и тому же набору строк. Поскольку альтернативные версии берутся слева направо, и установленные опции сохраняют свое действие до конца подмаски, опция, установленная в одной ветке, также имеет эффект во всех последующих ветках. Поэтому приведенные выше шаблоны совпадают как с 'SUNDAY', так и с 'Saturday'.

    Также можно использовать именованные подмаски с помощью синтаксиса (?Ppattern). Эта подмаска будет индексирована в массиве совпадений кроме обычного числового индекса, еще и по имени name. В PHP 5.2.2 было добавлено два альтернативных синтаксиса: (?pattern) и (?'name'pattern).

    Иногда бывает необходимо иметь несколько совпадений, исключающих друг друга. Обычно, каждое такое совпадение получает свой собственный номер, даже если шаблон позволяет совпасть только одному из них. Синтаксис (?| позволяет обойти это поведение и убрать дублирующиеся номера. Рассмотрим следующее регулярное выражение, сопоставленное со строкой Sunday:

    '(?:(Sat)ur|(Sun))day'

    Здесь Sun сохраняется в ссылке 2, тогда как ссылка 1 пуста. Если же совпадет Sat, то она будет помещена в ссылку 1, а ссылка 2 вообще не будет существовать. Использование (?| в шаблоне решает эту проблему, и обе подмаски Sun и Sat будут сохранены под номером 1.

    '(?|(Sat)ur|(Sun))day'

    Вне символьного класса обратный слеш с последующей цифрой больше нуля (и, возможно, последующими цифрами) интерпретируется как ссылка на предшествующую захватывающую подмаску, предполагая, что соответствующее количество предшествующих открывающих круглых скобок присутствует.

    Однако, в случае, если следующее за обратным слешем число меньше 10, оно всегда интерпретируется как обратная ссылка, и приводит к ошибке только в том случае, если нет соответствующего числа открывающих скобок. Другими словами, открывающие скобки не обязаны предшествовать ссылке для чисел меньше 10. 'Упреждающая обратная ссылка' может иметь смысл, если используется повторение и более поздняя подмаска участвует в ранней итерации. Более детальную информацию об обработке цифр после обратного слеша можно найти в разделе 'Обратный слеш'.

    пример:
    паттерн строка результат
    ~(sens|respons)e and \1ibility~ sense and sensibility, sense and responsibility, response and responsibility sense and sensibility, sense and responsibility, response and responsibility
    Обратная ссылка сопоставляется с частью строки, захваченной соответствующей подмаской, но не с самой подмаской. Таким образом шаблон (sens|respons)e and \1ibility соответствует 'sense and sensibility', 'response and responsibility', но не 'sense and responsibility'.
    ~((?i)rah)\s+\1~ rah rah, RAH RAH, RAH rah rah rah, RAH RAH, RAH rah
    В случае, если обратная ссылка обнаружена во время регистрозависимого поиска, то при сопоставлении обратной ссылки регистр также учитывается. Например, ((?i)rah)\s+\1 соответствует 'rah rah' и 'RAH RAH', но не 'RAH rah', хотя сама подмаска сопоставляется без учета регистра.

    На одну и ту же подмаску может быть несколько ссылок. Если подмаска не участвовала в сопоставлении, то сопоставление со ссылкой на нее всегда терпит неудачу. Например, шаблон (a|(bc))\2 терпит неудачу, если находит соответствие с 'a' раньше, чем с 'bc'. Поскольку может быть до 99 обратных ссылок, все цифры, следующие за обратным слешем, рассматриваются как часть потенциальной обратной ссылки. Если за ссылкой должна следовать цифра, необходимо использовать ограничитель. В случае, если указан флаг PCRE_EXTENDED, ограничителем может быть любой пробельный символ. В противном случае можно использовать пустой комментарий.

    Ссылка на подмаску, внутри которой она расположена, всегда терпит неудачу, если это первое сопоставление текущей подмаски. Например, шаблон (a\1) не соответствует ни одной строке. Но все же такие ссылки бывают полезны в повторяющихся подмасках. Например, шаблон (a|b\1)+ совпадает с любым количеством 'a', 'aba', 'ababaa'... При каждой итерации подмаски обратная ссылка соответствует той части строки, которая была захвачена при предыдущей итерации. Чтобы такая конструкция работала, шаблон должен быть построен так, чтобы при первой итерации сопоставление с обратной ссылкой не производилось. Этого можно достичь, используя альтернативы (как в предыдущем примере), либо квантификаторы с минимумом, равным нулю.

    Начиная с PHP 5.2.2, управляющая последовательность \g может быть использована для абсолютных и относительных ссылок на подмаски. После этой последовательности должно быть указано беззнаковое или отрицательное число, при желании заключенное в фигурные скобки. Последовательности \1, \g1 и \g{1} эквивалентны друг другу. Использование этого шаблона с беззнаковым числом поможет избежать двусмысленности, присущей числам после обратного слеша. Это также помогает отличить обратные ссылки от символов в восьмеричном формате, а также упрощает запись числового литерала сразу после обратной ссылки, например, \g{2}1.

    Использование отрицательных чисел с \g полезно при использовании относительных ссылок. Например, (foo)(bar)\g{-1} соответствует 'foobarbar', а (foo)(bar)\g{-2} соответствует 'foobarfoo'. Это также может быть полезно в длинных шаблонах, в качестве альтернативы отслеживания числа подмасок, на которые можно ссылаться в последующей части шаблона.

    Указать обратную ссылку на именованную подмаску можно с помощью (?P=name) или, начиная с PHP 5.2.2, \k или \k'name'. Кроме того, в PHP 5.2.4 была добавлена поддержка \k{name} и \g{name}, а в PHP 5.2.7 для \g и \g'name'.

    '(?i:saturday|sunday)'
    '(?:(?i)saturday|sunday)'

    Добыча элементов списка с помощью массива $matches, полученного встроенной функцией preg_match_all($pattern,$subject,$matches):

    1. Получаем массив $matches;
    2. Проверяем на пустоту подмассив $matches[$name_submask];
    3. Если подмассив пуст - совпадений не найдено. выход;
    4. Если подмассив не пуст - перебираем все его элементы и формируем вывод.
    пример работы функции preg_match_all_table($pattern,$subject,$name_submask):
    паттерн / имя подмаски ~<li>(.+?)</li>~ / 1
    строка
    	<p>небольшой абзац.</p>
    	<ul>
    		<li>первый элемент</li>
    		<li>второй элемент</li>
    		<li>третий элемент</li>
    	</ul>
    	<p>Смысл выражения очень прост..</p>
    $matches[1] 'первый элемент';
    'второй элемент';
    'третий элемент';

    Но правильнее(?) и удобнее(?) пользоваться именованной подмаской:

    пример работы функции preg_match_all_table($pattern,$subject,$name_submask):
    паттерн / имя подмаски ~<li>(?<name_submask>.+?)</li>~ / name_submask
    строка
    	<p>небольшой абзац.</p>
    	<ul>
    		<li>первый элемент</li>
    		<li>второй элемент</li>
    		<li>третий элемент</li>
    	</ul>
    	<p>Смысл выражения очень прост..</p>
    $matches[name_submask] 'первый элемент';
    'второй элемент';
    'третий элемент';

    Вот пример неудачной попытки получить тело списка, который, казалось-бы, обязан сработать:

    пример работы функции preg_match_all_table($pattern,$subject,$name_submask):
    паттерн / имя подмаски ~<ul.+?>(?<top_menu>.+?)</ul>~ / top_menu
    строка
    </div><div id='product_description'><p>параграф перед списком</p>
    					<ul class='top_menu'>список
    						<li class='active'>Описание</li>
    						<li class>Характеристики</li>
    						<li class>Условия работы</li>
    						<li class>Статьи</li>
    						<li class>Где купить</li>
    					</ul>
              <div class='item_description clearfix visible'><div class='item_description_text_left'>
    					<h2>Назначение</h2>
    $matches[top_menu] Совпадений не найдено (Массив $matches[top_menu] пуст).

    После долгих раздумий я прихожу к выводу, что в строку закрался пресловутый символ вертикальной табуляции, так как следующий паттерн все же выполняет задуманное:

    пример работы функции preg_match_all_table($pattern,$subject,$name_submask):
    паттерн / имя подмаски ~<ul.+?>(?<top_menu>[\s\S]+?)</ul>~ / top_menu
    строка
    </div><div id='product_description'><p>параграф перед списком</p>
    					<ul class='top_menu'>список
    						<li class='active'>Описание</li>
    						<li class>Характеристики</li>
    						<li class>Условия работы</li>
    						<li class>Статьи</li>
    						<li class>Где купить</li>
    					</ul>
              <div class='item_description clearfix visible'><div class='item_description_text_left'>
    					<h2>Назначение</h2>
    $matches[top_menu] 'список <li class='active'>Описание</li> <li class>Характеристики</li> <li class>Условия работы</li> <li class>Статьи</li> <li class>Где купить</li> ';

    Удаление подстрок, соответствующих паттерну с помощью встроенной функции preg_replace($pattern,$replacement,$string) с использованием модификаторов 'iu':

    пример работы функции preg_replace($pattern,$replacement,$string):
    паттерн/строка замены '~<ul>.+?</ul>~iu' / ''
    строка <p>небольшой абзац.</p><ul><li>первый элемент</li><li>второй элемент</li><li>третий элемент</li></ul><p>Смысл выражения очень прост..</p>
    результат замены <p>небольшой абзац.</p><p>Смысл выражения очень прост..</p>

    Удаление всех тегов. Тег начинается и заканчивается угловыми скобками, первым символом может быть закрывающий слеш либо латинская буква, затем практически все, что угодно: '[a-zA-Z0-9' :;="/а-яФА-Я-]', между угловыми скобками должен быть хоть один символ:

    пример работы функции preg_replace($pattern,$replacement,$string):
    паттерн/строка замены '~<[/]?[/a-zA-Z][a-zA-Z0-9'_ :;="/а-яА-Я.-]*>~iu' / ' '
    строка <p>небольшой абзац.</p><!-- комментарий --><-- не тег и не комментарий --><ul class='uuy'><li style='color:red;'>первый элемент</li><li>второй элемент</li><li>третий элемент</li><li><img src='URL' alt='альтернативный текст' /></li></ul><p>Смысл выражения очень прост..</p>
    результат замены небольшой абзац. <!-- комментарий --><-- не тег и не комментарий --> первый элемент второй элемент третий элемент Смысл выражения очень прост..

    Второй вариант удаления всех тегов. Тег начинается и заканчивается угловыми скобками, первым символом может быть закрывающий слеш либо латинская буква, затем ВСЕ, что угодно, кроме закрывающей скобки: '[^>]', и между угловыми скобками должен быть хоть один символ::

    пример работы функции preg_replace($pattern,$replacement,$string):
    паттерн/строка замены '~<[/]?[/a-zA-Z][^>]*>~iu' / ' '
    строка <p>небольшой абзац.</p><!-- комментарий --><-- не тег и не комментарий --><ul class='uuy'><li style='color:red;'>первый элемент</li><li>второй элемент</li><li>третий элемент</li><li><img src='URL' alt='альтернативный текст' /></li></ul><p>Смысл выражения очень прост..</p>
    результат замены небольшой абзац. <!-- комментарий --><-- не тег и не комментарий --> первый элемент второй элемент третий элемент Смысл выражения очень прост..

    Удаление всех тегов и комментариев. Тег начинается и заканчивается угловыми скобками, первым символом может быть закрывающий слеш либо латинская буква, затем ВСЕ, что угодно, кроме закрывающей скобки: '[^>]', и между угловыми скобками должен быть хоть один символ::

    пример работы функции preg_replace($pattern,$replacement,$string):
    паттерн/строка замены '~<[/]?[/a-zA-Z!][^>]*>~iu' / ' '
    строка <p>небольшой абзац.</p><!-- комментарий --><-- не тег и не комментарий --><ul class='uuy'><li style='color:red;'>первый элемент</li><li>второй элемент</li><li>третий элемент</li><li><img src='URL' alt='альтернативный текст' /></li></ul><p>Смысл выражения очень прост..</p>
    результат замены небольшой абзац. <-- не тег и не комментарий --> первый элемент второй элемент третий элемент Смысл выражения очень прост..

    Для получения из исходного кода подстроки, содержащей только набор нормативных документов воспользуемся функцией preg_replacement($pattern,$replacementment,$string), указав в качестве первой подмаски все выражение, а в качестве строки замены - ссылку на вторую подмаску.

    пример работы функции preg_replace($pattern,$replacement,$string):
    паттерн/строка замены '~(^.+?Изготавлива(?:ются|ется) в соответствии с требованиями (.+?)\.</p>.+)$~' / '$2'
    строка <span>Обратная ссылка сопоставляется с частью строки, захваченной соответствующей подмаской, но не с самой подмаской.</span><div class='discription_with_icons'><p>Изготавливаются в соответствии с требованиями ТР ТС 010/2011,<br />РД 24-СЗК-01-01, ФНП ПБ ОПО.</p> <p>Стропы из текстильной ленты российского производства.<br />Смысл выражения очень прост...</p>
    результат замены ТР ТС 010/2011,<br />РД 24-СЗК-01-01, ФНП ПБ ОПО