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

Содержание

Как использовать preg_replace_callback?

У меня есть следующий HTML-оператор

То, что я пытаюсь сделать, это заменить теги [otsection] на html div. Уловкой я хочу увеличить id div от 1- > 2- > 3 и т.д.

Так, например, приведенный выше оператор должен быть переведен на

Насколько я могу исследовать, лучший способ сделать это — использовать preg_replace_callback для увеличения переменной id между каждой заменой. Но после 1 часа работы над этим, я просто не могу заставить его работать.

Любая помощь с этим будет высоко оценена!

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

Кроме того, обратите внимание, что я добавил ots в идентификатор. Идентификаторы элементов не должны начинаться с цифр.

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

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

Когда следует использовать его?

preg_replace_callback() очень похож на preg_replace() — единственное отличие заключается в том, что вместо указания строки замены для второго параметра, вы указываете функцию callback .

Используйте preg_replace() , если вы хотите выполнить простой поиск и замену регулярных выражений. Используйте preg_replace_callback() , если вы хотите сделать больше, чем просто заменить. См. Пример ниже, чтобы понять, как он работает.

Как его использовать?

Вот пример, иллюстрирующий использование функции. Здесь мы пытаемся преобразовать строку даты из YYYY-MM-DD в формат DD-MM-YYYY .

Здесь наш шаблон регулярного выражения ищет строку даты формата NNNN-NN-NN , где N может быть цифрой в диапазоне от 0 — 9 ( \d является сокращенным представлением для класса символов [0-9] ). Функция callback будет вызываться и передан массив согласованных элементов в данной строке.

Конечным результатом будет:

Примечание: Приведенный выше пример предназначен только для иллюстрации. Вы не используете для синтаксического анализа дат. Вместо этого используйте DateTime::createFromFormat() и DateTime::format() . Этот вопрос содержит более подробную информацию.

Работа с функцией preg_replace_callback

Primary tabs

Forums:

Пришлось работать с функцией preg_replace_callback. Это весьма сильная вещь, так как позволяет быстро и изящно обработать сложные текcтовые конструкции. Отличие данной функции от preg_replace состоит в том, что можно передать свою собственную функцию с нетривиальной логикой для обработки текстовых совпадений.
Стоит отметить, что в обеих функциях есть возможность обращаться к совпадениям, найденным регулярным выражениям как к переменным. $k — совпадение с k-ой подмаской в регулярке (также можно обращаться \\k— однако первый вариант предпочтительней. ) $0 — совпадение со всем выражением.

Например следующий код

#», «$1«, $text);

Данный код закодирует все html-теги внутри #si’, «myFunction», $text);

Новинки в PHP7. Часть 7.

Всем привет! В этой заключительной статье из серии мы рассмотрим новую функцию для работы с регулярными выражениями в PHP7.

Функция называется preg_replace_callback_array(). Те, кто знаком с функциями preg_replace() и preg_replace_callback(), думаю, уже поняли, что новая функция – это результат объединения этих двух.

Итак, давайте дадим определение:

preg_replace_callback_array – функция, позволяющая выполнить поиск и замену по регулярному выражению с использованием функции обратного вызова.

Описание

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

Параметры

  • patterns_and_callbacks – ассоциативный массив(ключ –> значение)
  • subject – строка или массив со строками для поиска и замены
  • limit – максимально возможные замены для каждого шаблона в каждой строке. По умолчанию -1(нет ограничений)
  • count – будет отображать количество выполненных замен, если указана

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

Функция возвращает массив, если subject – массив, или строку в другом случае. Если есть ошибки, возвращает NULL.

Если найдены совпадения, новый subject будет возвращен, иначе subject будет возвращен неизмененным.

Итак, на этом все. Теперь вы знаете основные улучшения в PHP7 и можете использовать их в своих проектах.

Спасибо за внимание!

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Она выглядит вот так:

  • BB-код ссылки для форумов (например, можете поставить её в подписи):
  • Комментарии ( 2 ):

    . int &$count ]]. Убрали же, вроде, передачу по указателю

    Добрый вечер, Михаил. У меня к вам вопрос такой, как вы считаете, может ли человек качественно верстать, быть настоящим гуру в верстке, и, при этом быть хорошим backend разработчиком? т.е возможно делать и первое, и второе без потери качества?

    Для добавления комментариев надо войти в систему.
    Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.

    Copyright © 2010-2020 Русаков Михаил Юрьевич. Все права защищены.

    Регулярные выражения для чайников

    Что такое регулярные выражения?

    В народе: регэкспы, регулярки.

    По-простому — это выражения для поиска и замены подстроки по шаблону.

    В PHP используется название PCRE (Perl Compatible Regular Expressions —
    перл совместимые регулярные выражения). В этой статье я постараюсь раскрыть
    потенциал это мощного инструмента программиста. Не пытайтесь понять все сразу,
    впитывайте порциями и приходите за добавкой.

    Начнем

    // наша строка для испытаний
    $string = ‘abcdefghijklmnopqrstuvwxyz0123456789’ ;

    Если нам нужно просто узнать есть ли шаблон ‘abc’ в строке $string
    мы можем набросать такой код:

    echo preg_match ( «/abc/» , $string ) ;
    ?>

    Этот код выведет ‘1’. Потому что он нашел 1 (одно) вхождение шаблона в строке.
    Если шаблон в строке не обнаружен, preg_match вернет 0. При нахождении первого вхождения,
    функция сразу возвращает результат! Дальнейший поиск не продолжается (см. preg_match_all)

    Нахождение начала строки

    Теперь мы желаем узнать, начинается ли строка с ‘abc’.
    Символ начала строки в регулярках — ‘^’ (caret — знак вставки).

    // тест на начало строки
    if ( preg_match ( «/^abc/» , $string ) )
    <
    // окей, строка начинается с абс
    echo ‘The string begins with abc’ ;
    >
    else
    <
    echo ‘это фэйл’ ;
    >
    ?>

    Пример выведет:
    The string begins with abc

    Оборачивающие слэши — разделители, содержат регуряное выражение. Это могут быть любые парные символы,
    например @regex@, #regex#, /regex/ и .т.п.

    Символ ^ сразу после первого разделителя указывает что выражение начинается сначала строки и НИКАК иначе.

    Что делать с регистром символов (строчные-прописные)

    Перепишем код, чтобы он искал строку ‘ABC’:

    Скрипт вернет:
    Не думаю

    Все потому что поиск регистро-зависимый. Шаблон ‘abc’ не тоже самое что ‘ABC’.
    Чтобы найти оба варианта, нужно использовать модификатор. В регулярных выражениях
    для этого применяется модификатор ‘i’, который нужно указать за закрывающим разделителем
    регулярного выражения.

    if ( preg_match ( «/^ABC/i» , $string ) ) <
    echo ‘Совпадение, строка начинается с abc’ ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>

    Теперь скрипт найдет паттерн ‘abc’. Также теперь будут попадать под шаблон
    строки вида abc, ABC, Abc, aBc, и т.п.

    Позже будет рассказано подробнее о модификаторах.

    Как указать в паттерне конец строки

    Делается это также как и в случае с поиском начала строки.
    Распространенная ошибка, допускаемя многими прогерами — использование символа $ для указания конца строки в шаблоне.
    Это неверно, правильное решение — использовать утверждение \z. Посмотрите на этот код

    Сниппет вернет true, потому что $ = \Z, что в свою очередь можно описать выражением (?=\z|\n\z).
    Когда нам нужно получить в результате строку без «разделителей строк», $ не должен использоваться.
    Также $ совпададет больше одного раза с модификатором /m, в противоположность \z. Изменим немного код,
    удалим каретку (^) в начале паттерна и добавим \z в конце, также уберем зависимость от регистра модификатором /i.

    // паттерн в конце строки?
    if ( preg_match ( «/89 \z /i» , $string ) ) <
    echo ‘Совпадение, строка заканчивается на 89’ ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    >> Совпадение, строка заканчивается на 89

    Потому что мы определили конец строки 89. Вот так.

    Мета символы

    Ранее мы поэкспериментировали с простыми регулярками. Познакомились с кареткой (^) и долларом ($)/
    Эти символы имееют особенное значение. Каретка (^) обозначает начало страки и доллар ($) — ее конец.
    Такие символы в купе с остальными специальными называются мета символами (meta characters).

    Список мета символов в регулярных выражениях:

    Разберем все символы на примерах.
    Если вам нужно составить шаблон в котором содержится такой символ, его необходимо экранировать (см. preg_quote)
    Например шаблон: «1+1», нужно записать как-то так:

    // образец
    $string = ‘1+1=2’ ;

    if ( preg_match ( «/^1 \+ 1/i» , $string ) ) <
    // yep
    echo ‘The string begins with 1+1’ ;
    > else <
    // nope
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    The string begins with 1+1

    Потому что интерпретатор проигнорировал специальное значение символа «+», обозначенного символом экранирования «\» (бэкслэш).
    Если бы мы не добавили экран к плюсу, то preg_match(«/^1+1/i», $string) не нашло бы совпадений с шаблоном.
    Сам бэкслэш в свою очередь тоже нужно экранировать, если мы ищем именно этот символ «\\».

    Что означают остальные мета символы

    Квадратные скобки [ ] обозначают «строковой класс».

    Символьный класс. Это просто набор символов, которые должны совпасть в искомой строке.
    Они могут записываться индивидуально (по одному):

    Или как диапазон, разделенный символом «-«:

    // Ищем шаблон
    echo preg_match ( «/b[aoiu]g/» , $string , $matches ) ;

    Результат скрипта:
    return 1

    Потому что preg_match() нашел совпадение.
    Этот код также найдет совпадение со строками ‘bag’ ‘bog’ ‘big’, но не с ‘beg’.
    Диапазон символов [a-f] равнозначен такой записи [abcdef]. Словами формулируется так [от ‘a’ до ‘f’].
    Еще раз повторю, выражения регистрозависимые, и [A-F] не тоже самое что и [a-f].

    Мета символы не работыют внутри классов, поэтому их не нужно экранировать внутри квадратных скобок [. ].
    Например класс [abcdef$] совпадет с символами a b c d e f $. Доллар ($) внутри класса — это простой бакс знак доллара без какого либо специального мета-свойства.

    Есть правда исключения из правил:
    Одна из полезных функций регулярных выражений — возможность указать шаблон НЕ совпадающий с диапазоном символов.
    Чтобы это сделать, нужно использовать каретку (^) первым символом класса.
    Найдем любые символы, кроме «b»:

    // осуществляем поиск
    preg_match ( «/[^b]/» , $string , $matches ) ;

    // выведем все совпадения в цикле foreach
    foreach ( $matches as $key => $value ) <
    echo $key . ‘ -> ‘ . $value ;
    >
    ?>

    Результат скрипта:
    0 -> a

    Здесь preg_match() нашел первое совпадение с шаблоном /[^b]/.
    Изменим скрипт и используем preg_match_all() для нахождения всех вхождений соответствующих шаблону /[^b]/.

    // ищем ВСЕ совпадения
    preg_match_all ( «/[^b]/» , $string , $matches ) ;

    // выведем все совпадения в цикле foreach
    foreach ( $matches [ 0 ] as $value ) <
    echo $value ;
    >
    ?>

    Результат скрипта:
    acefghijklmnopqrstuvwxyz0123456789

    Выведет все символы, которые НЕ совпадают с шаблоном «b».

    Так мы можем отфильтровать все цифры в строке:

    // все символы не являющиеся цифрами от 0 до 9
    preg_match_all ( «/[^0-9]/» , $string , $matches ) ;

    foreach ( $matches [ 0 ] as $value ) <
    echo $value ;
    >
    ?>

    Результат скрипта:
    abcefghijklmnopqrstuvwxyz

    Шаблон [^0-9] расшифровывается как все НЕ включая цифры от 0 до 9.

    Продолжаете слушать нашу радиостанцию?
    Тогда продолжим.

    Метасимвол Бэкслэш (\).

    Основное значение — экранирование других метасимволов.

    // create a string
    $string = ‘This is a [templateVar]’ ;

    // try to match our pattern
    preg_match_all ( «/[ \[ \] ]/» , $string , $matches ) ;

    // loop through the matches with foreach
    foreach ( $matches [ 0 ] as $value ) <
    echo $value ;
    >
    ?>

    Здесь мы хотели найти все символы []. Без экранирования шаблон выглядел бы так — «/[[]]/»,
    но мы добавили бэеслэши к скобкам [], чтобы отменить их мета-статус.
    Также, к примеру, поступим с путем к файлу.
    c:\dir\file.php
    В паттерне будем использовать разделитель «\\».

    Бэкслэш также ортодоксально используется в строках для указания специальных последовательностей: \n, \r и др.

    Еще он неймспейсы разделяет!

    Следующий символ «.» (точка) ака «полный стоп».

    `Точка` совпадает с любым символом кроме символов разрыва строки \r или \n.
    С помощью точки мы можем найти любой одиночный символ, за исключением разрыва строки.
    Чтобы точка также совпадала с переводом каретки и разрывом строки, можно использовать флаг /s.

    Ищем одиночный символ

    $string = ‘sex at noon taxes’ ;

    echo preg_match ( «/s.x/» , $string , $matches ) ;
    ?>

    Результат скрипта:
    1

    Да, да preg_match() нашел одно совпадение. Пример также сработает с sax, six, sox, sux, и s x, но не совпадет с «stix».

    Теперь попробуем найти \n.

    // create a string
    $string = ‘sex’ . » \n » . ‘at’ . » \n » . ‘noon’ . » \n » . ‘taxes’ . » \n » ;

    // echo the string
    echo nl2br ( $string ) ;

    // look for a match
    echo preg_match_all ( «/ \s /» , $string , $matches ) ;

    Результат скрипта:
    sex
    at
    noon
    taxes
    4

    preg_match_all() нашел 4 совпадения разрыва строки «\n» потому что мы использовали флаг \s. Подробнее про флаге в разделе Спец Последовательностей..

    Следующий волшебный символ — звездочка (*) asterisk
    Совпадает с НОЛем и/или БОЛЕЕ вхождений шаблона, находящегося перед звездочкой.
    * означает опциональный шаблон — допускается что символы могут быть, а могут и отсутствовать в строке.
    Так шаблон .* совпадает с любым количеством любых символов. Пример:

    // create a string
    $string = ‘php’ ;

    // look for a match
    echo preg_match ( «/ph*p/» , $string , $matches ) ;

    Результат скрипта:
    1

    Нашлось одно совпадение. В примере это один символ «h».
    Пример также совпадет также со строкой «pp» (ноль символов «h»), и «phhhp» (три символа «h»).

    Добрались до мета символа символа «+»

    Плюс почти тоже самое что и звездочка, за исключением того что плюс совпадает с ОДНИМ и БОЛЬШЕ символом.
    Так в примере звездочка «*» совпала со строкой ‘pp’, с плюсом «+» такое не пройдет.

    // create a string
    $string = ‘pp’ ;

    // look for a match
    echo preg_match ( «/ph+p/» , $string , $matches ) ;

    Результат скрипта:

    Потому что ни одного символа «h».

    Следубщий пациент
    Мета символ «?»

    Знак вопроса совпадет с НУЛЕМ или ОДНИМ вхождением символа или регулярным выражением,
    указанным сразу перед ним. Полезен для указания опциональных символов (которых может и не быть).

    Например, телефонный номер в Австралии: 1234-5678.

    // create a string
    $string = ‘12345678’ ;

    // look for a match
    echo preg_match ( «/1234-?5678/» , $string , $matches ) ;

    Результат скрипта:
    1

    Потому что -? совпал 0 раз с символом «-«. Изменение строки на «1234-5678» выдаст тот же результат.

    Фигурные скобки <>

    Указывает на количество совпавших символов или их интервал.
    Например, за фразой PHP должно следовать ТОЧНО ТРИ цифры:

    // create a string
    $string = ‘PHP123’ ;

    // look for a match
    echo preg_match ( «/PHP[0-9]<3>/» , $string , $matches ) ;

    Результат скрипта:
    1

    Шаблон PHP 0-9(цифры от 0 до 9) <3>(три раза) совпал.

    Специальные последовательности

    Бэкслэш (\) используется для спец. последовательностей:

    * \d — любая цифра (тоже самое что и [0-9])
    * \D — любая НЕ цифра ([^0-9])
    * \s — все «недосимволы» — пробелы, переводы строки, табуляция ([ \t\n\r\f\v])
    * \S — все НЕ «недосимволы» ([^ \t\n\r\f\v])
    * \w — все альфа-цифровые символы (буквенно-числовые) ([a-zA-Z0-9_])
    * \W — все НЕ альфа-цифровые символы ([^a-zA-Z0-9_])

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

    // match our pattern containing a special sequence
    preg_match_all ( «/[ \w ]/» , $string , $matches ) ;

    // loop through the matches with foreach
    foreach ( $matches [ 0 ] as $value ) <
    echo $value ;
    >
    ?>

    Результат скрипта:
    abcefghijklmnopqrstuvwxyz0123456789

    Мы нашли (preg_match_all) все цифры и буквы (\w) класса ( [] ).

    На следующем примере мы можем убедиться, что строка не содержит чисел.

    // create a string
    $string = ‘2 bad for perl’ ;

    // echo our string
    if ( preg_match ( «/^ \d /» , $string ) ) <
    echo ‘String begins with a number’ ;
    > else <
    echo ‘String does not begin with a number’ ;
    >
    ?>

    Метасимвол «.» (Точка, полный стоп)

    Совпадает один раз с любым символом (кроме разрыва строки)

    // create a string
    $string = ‘abcdefghijklmnopqrstuvwxyz0123456789’ ;

    // try to match any character
    if ( preg_match ( «/./» , $string ) ) <
    echo ‘The string contains at least on character’ ;
    > else <
    echo ‘String does not contain anything’ ;
    >
    ?>

    Результат скрипта:
    The string contains at least on character

    Конечно, код содержит хотябы один символ.

    Ранее была рассмотрена проблема нахождения символа разрыва строки, потому что «.» не совпадает с таким символом (\n).
    Здесь нам на помощь придет флаг \s. Он найдет любой пробельный символ (недосимвол).

    Для примера используем \n.

    // create a string
    $string = ‘sex’ . » \n » . ‘at’ . » \n » . ‘noon’ . » \n » . ‘taxes’ . » \n » ;

    // echo the string
    echo nl2br ( $string ) ;

    // look for a match
    echo preg_match_all ( «/ \s /» , $string , $matches ) ;

    Результат скрипта:
    sex
    at
    noon
    taxes
    4

    preg_match() нашел 4 совпадения перевода строки \n.

    Теперь все вместе, хором

    Более сложные выражения.
    Рассмотрим оператор OR (ИЛИ).
    В регулярных выражениях это символ «|» (труба, канал).

    Настало время показательного «Hello World» скрипта.

    // a simple string
    $string = «This is a Hello World script» ;

    // try to match the patterns This OR That OR There
    echo preg_match ( «/^(This|That|There)/» , $string ) ;
    ?>

    Усложним задачу: попытаемся найти одновременно Hello или Jello в строке.

    // a simple string
    $string = «This is a Hello World script» ;

    // try to match the patterns Jello or Hello
    if ( ! preg_match ( «/(Je|He)llo/» , $string ) ) <
    echo ‘Pattern not found’ ;
    > else <
    echo ‘pattern found’ ;
    >
    ?>

    Хотя шаблон совпал, мы не видим какую имеено сроку мы нашли.
    Для возвращения найденных результатов в preg_match добавляется третий параметр (&$matches):

    // a simple string
    $string = «This is a Hello World script» ;

    // try to match the patterns Jello or Hello
    // put the matches in a variable called matches
    preg_match ( «/(Je|He)llo/» , $string , $matches ) ;

    // loop through the array of matches and print them
    foreach ( $matches as $key => $value ) <
    echo $key . ‘->’ . $value . ‘
    ‘ ;
    >
    ?>

    Элемент массив $matches[0] содержит всю совпавшую подстроку (всегда), в примере — Hello.
    Последующие элементы содержат последовательно вхождения субпаттернов «()».
    $matches[1] совпадает с первым субпатерном. В примере — (Je|He)

    Модификаторы и утверждения

    Модификаторы изменяют поведения шаблонов регулярных выражений.

    i — регистронезависимый (Ignore Case, case insensitive)
    U — нежадный поиск (Make search ungreedy)
    s — включая перевод строки (Includes New line)
    m — мультистрока (Multiple lines)
    x — Extended for comments and whitespace
    e — Enables evaluation of replacement as PHP code. (preg_replace only)
    S — Extra analysis of pattern

    b — граница слова (Word Boundry)
    B — НЕ граница слова (Not a word boundary)
    A — начало шаблона (Start of subject)
    Z — конец шаблона или разрыв строки (End of subject or newline at end)
    z — конец шаблона (End of subject)
    G — первая совпавшая позиция в шаблоне (First matching position in subject)
    ?>

    Простой пример модификатора «i»

    // create a string
    $string = ‘abcdefghijklmnopqrstuvwxyz0123456789’ ;

    // try to match our pattern
    if ( preg_match ( «/^ABC/i» , $string ) ) <
    echo ‘Совпадение, строка начинается с abc’ ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>
    ?>

    Использование модификатора «s»

    /*** create a string with new line characters ***/
    $string = ‘sex’ . » \n » . ‘at’ . » \n » . ‘noon’ . » \n » . ‘taxes’ . » \n » ;

    /*** look for a match */
    echo preg_match ( «/sex.at.noon/» , $string , $matches ) ;

    Результат скрипта:

    «.» не находит символы разрыва строки, добавим модификатор «s»
    чтобы это исправить

    /*** create a string with new line characters ***/
    $string = ‘sex’ . » \n » . ‘at’ . » \n » . ‘noon’ . » \n » . ‘taxes’ . » \n » ;

    /*** look for a match using s modifier ***/
    echo preg_match ( «/sex.at.noon/s» , $string , $matches ) ;
    ?>
    ?>

    Результат скрипта:
    1

    Разрывы строк позволяют нам использовать модификатор «m».
    Это улично-магический модификатор. Он принимает строку за однострочнкую с символом разрыва на конце,
    даже если в строке на самом деле больше символов разрыва (мультистрока).
    Т.е. если в строке нет символов разрыва строк, этот модификатор ничего не значит.

    // create a string
    $string = ‘sex’ . » \n » . ‘at’ . » \n » . ‘noon’ . » \n » . ‘taxes’ . » \n » ;

    // look for a match
    if ( preg_match ( «/^noon/im» , $string ) ) <
    echo ‘Pattern Found’ ;
    > else <
    echo ‘Pattern not found’ ;
    >
    ?>

    Результат скрипта:
    Pattern Found

    Конечно регулярное выражение найдет совпадение.
    Все что следует после первого символа разрыва строки отбрасывается из-за модификатора «m».

    В примере используюся вместе модификаторы «i» и «m», их действие комбинируется.

    «x» модификатор позволяет составлять регулярное выражение на нескольких строках,
    что повышает его читабельность и позволяет добавлять комментарии внутри шаблона.

    // create a string
    $string = ‘sex’ . » \n » . ‘at’ . » \n » . ‘noon’ . » \n » . ‘taxes’ . » \n » ;

    // create our regex using comments and store the regex
    // in a variable to be used with preg_match
    $regex = ‘
    / # opening double quote
    ^ # caret means beginning of the string
    noon # the pattern to match
    /imx
    ‘ ;

    // look for a match
    if ( preg_match ( $regex , $string ) ) <
    echo ‘Pattern Found’ ;
    > else <
    echo ‘Pattern not found’ ;
    >
    ?>

    Код в пояснениях не нуждается, он просто демонстрирует как можно вставить комментарии и
    написать выражение в несколько строк.

    Модификатор «e»

    Спец млжификатор, который изменяет выполнение сопоставления шаблону. Ниже будет выделена целая секция для его описания.

    Модификатор «S»

    Этот модификатор позволяет нам проанализировать строку до сопостовления с шаблонами,
    которые не помечены якорями. Т.е. если шаблон не имеет начальной фиксированой позиции, как например:

    Паттерн может успорить выполение шаблона в случае с множественными совпадениями.
    В следующем примере появляется множественное вхождение шаблона, поэтому добавим «S».

    // match our pattern containing a special sequence
    preg_match_all ( «/[ \w ]/S» , $string , $matches ) ;

    // loop through the matches with foreach
    foreach ( $matches [ 0 ] as $value ) <
    echo $value ;
    >
    ?>

    Результат скрипта:
    abcefghijklmnopqrstuvwxyz01234567890

    На практике модификатор используется достаточно редко.

    Модификатор границы слова (word boundary) «\b»

    Граница слова создается между двух «\b» модификаторов.
    Это специальный «подпирающий тип модификаторов, которые позволяют указть ТОЧНОЕ совпадение.
    Текст должен совпасть только с точным шаблоном заключенным в «\b»
    Например, шаблон «cat» не совпадет с «catalog».

    $string = ‘eregi will not be available in PHP 6’ ;

    // ищем строку «lab»
    if ( preg_match ( «/ \b lab \b /i» , $string ) ) <
    // Совпадение
    echo $string ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    Не думаю

    Мы пытаемся найти совпадение с паттерном «lab», которое находится внутри строки в слове «available».
    Из за использования границ слов, шаблон не совпал с подстрокой.
    Давайте попробуем пример, не используя модификатора границ слов.

    $string = ‘eregi will remain in the computer lab’ ;

    // ищем строку «lab»
    if ( preg_match ( «/ \b lab \b /i» , $string ) ) <
    // Совпадение
    echo $string ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    eregi will remain in the computer lab

    Мы видим что совпадение произошло с целым словом «lab». (\blab\b).

    Модификатор \B

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

    $string = ‘This lathe turns wood.’ ;

    // match word boundary and non-word boundary
    if ( preg_match ( «/ \B the \b /» , $string ) ) <
    echo ‘Совпал шаблон «the».’ ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    >> Совпал шаблон «the».

    Этот код сначала найдет паттерн «the». Потому что сначала указан модификатор «не граница слова»,
    the находится внутри фразы и не снача ее, затем модификатор \b границы указывает что фраза должна
    закончится на -the.

    $string = ‘The quick brown fox jumps over the lazy dog.’ ;

    // match word boundary and non-word boundary
    if ( preg_match ( «/ \B the \b /» , $string ) ) <
    echo ‘Совпал шаблон «the».’ ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    Не думаю

    В этот раз мы ничего не нашли, потому что «the» стоит на границе слова, а мы использовали модификатор \B.

    Последний модификатор — \U

    По умолчанию, PCRE «жадный» — это не значит что они съедят вашу печеньку,
    а означает что шаблон совпадет с наибольшим возможным количеством символов,
    попадающих под этот шаблон.

    Чтобы отключить такую «жадность» регулярных выражений
    — используем ограничитель «?», например «(.*?)»
    — используем модификатор «\U».

    Новичкам желательно использовать этот модификатор по-умолчанию, чтобы не возникало конфузов.

    $string = ‘foobar foo—bar fubar’ ;

    // try to match the pattern
    if ( preg_match ( «/foo(.*)bar/U» , $string ) ) <
    echo ‘Совпадение’ ;
    > else <
    echo ‘Не думаю’ ;
    >

    Результат скрипта:
    Совпадение

    Другой пример — дан кусок html

    Попытаемся найти все ссылки выражением preg_match_all(«/.*/s», $string),
    код вернет всю искомую строку вместо трех ссылок. Добавив Нежадный модификатор, все три ссылки поотдельности.

    Вычисление с preg_replace

    Приветствуем на сцене модификатор «e».

    Этот модификатор вычисляет заменяемый аргумент.
    До этого мы не рассматривали preg_replace(), поэтому быстрый пример:

    $string = ‘We will replace the word foo’ ;

    // заменяем `for` на `bar`
    $string = preg_replace ( «/foo/» , ‘bar’ , $string ) ;

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

    // строка с шаблонными переменными
    $string = ‘This is the <_foo_>bought to you by <_bar_>‘ ;

    // создади массив со значениями переменных
    $templateVars = [ «FOO» => «The PHP Way» , «BAR» => «PHPro.orG» ] ;

    // заменяем и вычисляем
    $string = preg_replace ( «/<_(.*?)_>/ime» , » \$ templateVars[‘$1’]» , $string ) ;

    Без модификатора «е» скрипты выдаст результат:
    This is a $template_vars[FOO] and this is a $template_vars[BAR]

    С модификатором переменные вычислятся после замены:
    This is the The PHP Way bought to you by PHPro.orG

    Таким образом, модификатор «e» обладает потенциалом встроенного шаблонизатора.

    Заглядывание вперед (Look Aheads)

    Возможность регулярных выражений «заглянуть вперед» шаблона для определения дальнейших совпадений.
    «Подглядывание вперед» бывает положительное и отрицательное

    Рассмотрим сначала заглядывание вперед с отрицанием. Обозначается в шаблоне символами «?!».
    Полезно при поиске шаблона, стоящего впереди от совпадения, которое нам нужно.

    $string = ‘I live in the whitehouse’ ;

    // try to match white not followed by house
    if ( preg_match ( «/white+(?!house)/i» , $string ) ) <
    // if we find the word white, not followed by house
    echo ‘Совпадение’ ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    No match is found

    Потому что слово «white» следует за словом «house».
    Подадим блюдо под другим соусом:

    $string = ‘I live in the white house’ ;

    // try to match white not followed by house
    if ( preg_match ( «/white+(?!house)/i» , $string ) ) <
    // if we find the word white, not followed by house
    echo ‘Совпадение’ ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    Совпадение

    Есть совпадение, потому что слово «white» не следует сразу же за словом «house» (как в «whitehouse»)

    Позитивное/положительное заглядывание вперед «?=»

    $string = ‘This is an example eg: foo’ ;

    // try to match eg followed by a colon
    if ( preg_match ( «/eg+(?=:)/» , $string , $match ) ) <
    print_r ( $match ) ;
    > else <
    echo ‘Нет совпадений’ ;
    >
    ?>

    Результат скрипта:
    Array < [0]=>‘eg’ >

    Код ищет паттерн «eg», стоящий перед «:» двоеточием.
    Но что если нам нужно найти что-то до двоеточия, например дом из предудыщего примера.
    Для этого на помощь приходят «заглядывания назад».

    Заглядывание назад (Look Behinds)

    Позволяет просмотреть строку назад и определить наличие совпадений с шаблоном.
    Также разделяется на положительное и отрицательное.
    Положительное — записывается «?

    $string = ‘I live in the whitehouse’ ;

    // try to match house preceded by white
    if ( preg_match ( «/(? , $string ) ) <
    // if we find the word white, not followed by house
    echo ‘Совпадение’ ;
    > else <
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    Совпадение

    Здесь мы нашли совпадение, потому что паттерн «house» сразу следует за паттерном «house».
    Движок регулярных выражений «посмотрел назад» шаблона «house» и определил совпадение.

    Если мы хотим, чтобы «house» НЕ следовал за словом «white»?
    Используем отрицительное заглядывание назад — «?

    /*** a simple string ***/
    $string = ‘I live in the whitehouse’ ;

    /*** try to match house preceded by white ***/
    if ( preg_match ( «/(? , $string ) )
    <
    /*** if we find the word white, not followed by house ***/
    echo ‘Совпадение’ ;
    >
    else
    <
    /*** if no match is found ***/
    echo ‘Не думаю’ ;
    >
    ?>

    Результат скрипта:
    no match is found

    Потому что отрицательное заглядывание не нашло шаблона «house» c шаблоном «white» в начале его.
    Давайте поменяем цвет «дома», белым слишком девственный для правительственного здания.

    $string = ‘I live in the bluehouse’ ;

    // ищем `house` с непредшествующим `white`
    if ( preg_match ( «/(? , $string ) ) <
    /*** if we find the word white, not followed by house ***/
    echo ‘Совпадение’ ;
    > else <
    /*** if no match is found ***/
    echo ‘Не думаю’ ;
    >
    ?>

    Мы изменили «whitehouse» на «bluehouse» и теперь наша регулярка сработала, потому что
    шаблон «white» не обнаружен перед «house».

    По-умолчанию регулярки жадные, это значит что квантификаторы (какое слово страшное)
    *, +, ? «пожирают» столько символов сколько могут.

    /*** 4 x and 4 z chars ***/
    $string = «xxxxzzzz» ;

    /*** greedy regex ***/
    preg_match ( «/^(.*)(z+)$/» , $string , $matches ) ;

    /*** results ***/
    echo $matches [ 1 ] ;
    echo «
    » ;
    echo $matches [ 2 ] ;
    ?>

    Первый паттерн (.*) совпал со всеми четыремя «x» и тремя из четырех символов «z».
    Сработала жадность — шаблон забрал столько символов, сколько было в искомой строке.
    Проще простого помочь перестать квантификаторам быть жадными, добавив «?» к квантификатору как в примере:

    /*** string of characters ***/
    $string = «xxxxzzzz» ;

    /*** a non greedy match ***/
    preg_match ( «/^(.*?)(z+)$/» , $string , $matches ) ;

    /*** show the matches ***/
    echo $matches [ 1 ] ;
    echo «
    » ;
    echo $matches [ 2 ] ;
    ?>

    Теперь $matches[1] содержит четыре «x» символа и $matches[2] четыре символа «z».
    Потому что квантификатор «?» изменил поведение шаблона с «взять как можно БОЛЬШЕ» на «взять как можно МЕНЬШЕ».

    Чтобы сделать нежадным весь шаблон, используем модификатор «U».

    /*** string of characters ***/
    $string = «xxxxzzzz» ;

    /*** a non greedy match ***/
    preg_match ( «/^(.*)(z+)$/U» , $string , $matches ) ;

    /*** show the matches ***/
    echo $matches [ 1 ] ;
    echo «
    » ;
    echo $matches [ 2 ] ;
    ?>

    Результат как в предыдущем примере.

    Подводные камни c ? и U

    Важно заметить, что модификатор «U» не только делает поиск нежадным, он инвертирует поведение жадности квантификатора «?».
    Если использовался квантификатор «?» и одновременно модификатор «U», действие «?» будет инвертировано.

    /*** string of characters ***/
    $string = «xxxxzzzz» ;

    /*** a non greedy match ***/
    preg_match ( «/^(.*?)(z+)$/U» , $string , $matches ) ;

    /*** show the matches ***/
    echo $matches [ 1 ] ;
    echo «
    » ;
    echo $matches [ 2 ] ;
    ?>

    Результат скрипта:
    xxxxzzz
    Delimiters

    В этом мане было рассмотрено много регулярок и все они разделялись слэшем «/».
    Иногда нам нужно находить в шаблоне слэш и когда он одновременно является разделителем регуляного выражения,
    нам придется экранировать каждый встречающийся слэш, что неудобно.

    Поэтому в качестве разделителя можно взять любой символ, например #, @, ^ и т.п.

    /*** get the host name from a url ***/
    preg_match ( ‘#^(?:http://)?([^/]+)#i’ , «http://www.phpro.org/tutorials» , $matches ) ;

    /*** show the host name ***/
    echo $matches [ 1 ] ;
    ?>

    Примеры

    // the string to match against
    $string = ‘The cat sat on the mat’ ;

    // match the beginning of the string
    echo preg_match ( «/^The/» , $string ) ;

    // match the end of the string
    // returns 1
    echo preg_match ( «/mat \z /» , $string ) ;

    // match anywhere in the string
    // returns 0 as no match was found for dog.
    echo preg_match ( «/dog/» , $string ) ;
    ?>

    Поиск нескольких шаблонов

    // the string to match against
    $string = ‘The cat sat on the matthew’ ;

    // matches the letter «a» followed by zero or more «t» characters
    echo preg_match ( «/at*/» , $string ) ;

    // matches the letter «a» followed by a «t» character that may or may not be present
    echo preg_match ( «/at?/» , $string ) ;

    // matches the letter «a» followed by one or more «t» characters
    echo preg_match ( «/at+/» , $string ) ;

    // matches a possible letter «e» followed by one of more «w» characters anchored to the end of the string
    echo preg_match ( «/e?w+ \z /» , $string ) ;

    // matches the letter «a» followed by exactly two «t» characters
    echo preg_match ( «/at<2>/» , $string ) ;

    // matches a possible letter «e» followed by exactly two «t» characters
    echo preg_match ( «/e?t<2>/» , $string ) ;

    // matches a possible letter «a» followed by exactly 2 to 6 «t» chars (att attt atttttt)
    echo preg_match ( «/at<2,6>/» , $string ) ;

    Запомните, preg_match() возвращает только 0 или 1, и останавливается после первого успешного нахождения шаблона.

    Чтобы найти все совпадения — используйте preg_match_all().

    Чит Шит

    \w — Any “word” character (a-z 0-9 _)
    \W — Any non “word” character
    \s — Whitespace (space, tab CRLF)
    \S — Any non whitepsace character
    \d — Digits (0-9)
    \D — Any non digit character
    . — (Period) – Any character except newline

    ^ — Start of subject (or line in multiline mode)
    $ — End of subject (or line in multiline mode)
    [ — Start character class definition
    ] — End character class definition
    | — Alternates, eg (a|b) matches a or b
    ( — Start subpattern
    ) — End subpattern
    \ — Escape character

    n- Zero or more of n
    n+ — One or more of n
    n? — Zero or one occurrences of n
    — n occurrences exactly
    — At least n occurrences
    — Between n and m occurrences (inclusive)

    i — Case Insensitive
    m — Multiline mode — ^ and $ match start and end of lines
    s — Dotall — . class includes newline
    x — Extended– comments and whitespace
    e — preg_replace only – enables evaluation of replacement as PHP code
    S — Extra analysis of pattern
    U — Pattern is ungreedy
    u — Pattern is treated as UTF-8

    \b — Word boundary
    \B — Not a word boundary
    \A — Start of subject
    \Z — End of subject or newline at end
    \z — End of subject
    \G — First matching position in subject

    (?=) — Positive look ahead assertion foo(?=bar) matches foo when followed by bar
    (?!) — Negative look ahead assertion foo(?!bar) matches foo when not followed by bar
    (? ) — Once-only subpatterns (?>\d+)bar Performance enhancing when bar not present
    (?(x)) — Conditional subpatterns
    (?(3)foo|fu)bar — Matches foo if 3rd subpattern has matched, fu if not
    (?#) — Comment (?# Pattern does x y or z)

    Дополнения от меня

    Posix символьные классы

    Дополнительные шорткуты для шаблонов. Могут применяться только внутри классов.
    Пример для поиска числа с пробелами — preg_match(«@[[:space:]\d]+@», $string)

    Внутренние модификаторы шаблонов

    Модификаторы m, s, x, U, X, J могут использоваться внутри шаблона.
    Например (?im) установит мультистроковой регистронезивисимый метод поиска для паттерна.
    Отключить внутренние модификаторы можно перечислив их через дефис, например (?im-sx)

    Пример:
    шаблон (?i:foo) совпадет с «FoO»

    Именованный «захват»

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

    Записывается: (? ), (?’name’) или (?P ).
    Раньше поддерживался только такой синтаксис: (?P ). [

    preg_match ( ‘/Name: (.+), Age: ( \d +)/’ , $text , $matches ) ;
    preg_match ( ‘/Name: (?P .+), Age: (?P \d +)/’ , $text , $matches ) ;
    ?>

    Результат скрипта:
    array(‘Name’ => ‘строка’, ‘Age’ => ‘число’)

    Замена через callback-функцию

    В php есть возможность указать функцию обратного вызова
    для совпадений, если нам нужно проделать с ними необычные вещи.
    Для этого используется preg_replace_callback.

    \s * \w |’ ,
    create_function (
    ‘$matches’ ,
    ‘return strtoupper($matches[0]);’
    ) ,
    $line
    ) ;
    ?>

    Данный код заменит все первые буквы в параграфах на заглавные.

    В php >= 5.3 callback-функцию можно записать в сокращенном виде

    \s * \w |’ ,
    function ( $matches ) <
    return strtoupper ( $matches [ 0 ] ) ;
    > ,
    $line
    ) ;
    ?>

    Регулярные выражения в PHP.

    Регулярные выражения позволяют найти в строке последовательности, соответствующие шаблону. Например шаблон «Вася(.*)Пупкин» позволит найти последовательность когда между словами Вася и Пупкин будет любое количество любых символов. Если надо найти шесть цифр, то пишем «[0-9]<6>» (если, например, от шести до восьми цифр, тогда «[0-9]<6,8>»). Здесь разделены такие вещи как указатель набора символов и указатель необходимого количества:

    Вместо набора символов может быть использовано обозначение любого символа — точка, может быть указан конкретный набор символов (поддерживаются последовательности — упоминавшиеся «0-9»). Может быть указано «кроме данного набора символов».

    Указатель количества символов в официальной документации по php называется «квантификатор». Термин удобный и не несет в себе кривотолков. Итак, квантификатор может иметь как конкретное значение — либо одно фиксированное («<6>»), либо как числовой промежуток («<6,8>»), так и абстрактное «любое число, в т.ч. 0» («*»), «любое натуральное число» — от 1 до бесконечности («+»: «document[0-9]+.txt»), «либо 0, либо 1» («?»). По умолчанию квантификатор для данного набора символов равен единице («document[0-9].txt»).

    Для более гибкого поиска сочетаний эти связки «набор символов — квантификатор» можно объединять в метаструктуры.

    Как всякий гибкий инструмент, регулярные выражения гибки, но не абсолютно: зона их применения ограничена. Например, если вам надо заменить в тексте одну фиксированную строку на другую, фиксированную опять же, пользуйтесь str_replace. Разработчики php слезно умоляют не пользоваться ради этого сложными функциями ereg_replace или preg_replace, ведь при их вызове происходит процесс интерпретации строки, а это серьезно потребляет ресурсы системы. К сожалению, это любимые грабли начинающих php-программистов.

    Пользуйтесь функциями регулярных выражений только если вы не знаете точно, какая «там» строка. Из примеров: поисковый код , в котором из строки поиска вырезаются служебные символы и короткие слова а так же вырезаются лишние пробелы (вернее, все пробелы сжимаются: » +» заменяется на один пробел). При помощи этих функций я проверяю email пользователя, оставляющего свой отзыв. Много полезного можно сделать, но важно иметь в виду: регулярные выражения не всесильны. Например, сложную замену в большом тексте ими лучше не делать. Ведь, к примеру, комбинация «(.*)» в программном плане означает перебор всех символов текста. А если шаблон не привязан к началу или концу строки, то и сам шаблон «двигается» программой через весь текст, и получается двойной перебор, вернее перебор в квадрате. Нетрудно догадаться, что еще одна комбинация «(.*)» означает перебор в кубе, и так далее. Возведите в третью степень, скажем, 5 килобайт текста. Получается 125 000 000 000 (прописью: сто двадцать пять миллиардов операций). Конечно же, если подходить строго, там стольких операций не будет, а будет раза в четыре-восемь меньше, но важен сам порядок цифр.

    Набор символов

    . точка любой символ
    [ ] квадратные скобки класс символов («любое из»). Например [abcdef]
    [^ ] негативный класс символов («любое кроме»)
    тире обозначение последовательности в классе символов («[0-9]» — цифры)
    \d [0-9] Только цифры
    \D [^0-9] Кроме цифр
    \w [a-z0-9] Буквы и цифры
    \W [^a-z0-9] Кроме букв и цифр
    \s [ ] Пробельные символы: пробел, табуляция, перевод строки
    \S [^ ] Кроме пробельных символов
    | (одно|другое) На этом месте может быть один из перечисленных вариантов, например: (Вася|Петя|Маша). Если Вы не хотите, чтобы это попало в выборку используйте (?: … )

    Не пользуйтесь классом символов для обозначения всего лишь одного (вместо «[ ]+» вполне сойдет » +»). Не пишите в классе символов точку — это ведь любой символ, тогда другие символы в классе будут просто лишними (а в негативном классе получится отрицание всех символов).

    Квантификатор

    Квантификатором можно указать как конкретное значение, так и пределы. Если число заданных подпадает под пределы квантификатора, фрагмент выражения считается совпавшим с разбираемой строкой. Синтаксис:

    Если нужно указать только необходимый минимум, а максимума нет, просто ставим запятую и не пишем второе число: «<5,>» («минимум 5»). Для наиболее часто употребляемых квантификаторов есть специальные обозначения:

    * «звёздочка» или знак умножения
    + плюс
    ? вопросительный знак

    На практике такие символы используются чаще, чем фигурные скобки.

    Якоря

    ^ привязка к началу строки
    $ привязка к концу строки

    Эти символы должны стоять соответственно в самом начале и в самом конце строки.

    Жадность

    Вопросительный знак выступает еще и как минимизатор квантификатора:
    .*?

    Результат работы примера:

    Строка шаблона, как вы уже заметили, начинается и заканчивается слэшами. После второго идут параметры:

    i регистронезависимый поиск
    m многостроковый режим. По умолчанию PCRE ищет совпадения с шаблоном только внутри одной строки, а символы «^» и «$» совпадают только с началом и концом всего текста. Когда этот параметр установлен, «^» и «$» совпадают с началом и концом отдельных строк.
    s символ «.» (точка) совпадает и с переносом строки (по умолчанию — нет)
    A привязка к началу текста
    E заставляет символ «$» совпадать только с концом текста. Игнорируется, если установлен парамерт m.
    U Инвертирует «жадность» для каждого квантификатора (если же после квантификатора стоит «?», этот квантификатор перестает быть «жадным»).
    e Строка замены интерпретитуется как PHP код.

    Функции для работы с регулярными выражениями

    • preg_grep — Возвращает массив вхождений, которые соответствуют шаблону
    • preg_match — Выполняет проверку на соответствие регулярному выражению. Данная функция ищет только первое совпадение!
    • preg_match_all — Выполняет глобальный поиск шаблона в строке
    • preg_quote — Экранирует символы в регулярных выражениях. Т.е. вставляет слэши перед всеми служебными символами (например, скобками, квадратными скобками и т.п.), чтобы те воспринимались буквально. Если у вас есть какой-либо ввод информации пользователем, и вы проверяете его с помощью регулярных выражений, то лучше перед этим заэкранировать служебные символы в пришедшей переменной
    • preg_replace — Выполняет поиск и замену по регулярному выражению
    • preg_replace_callback — Выполняет поиск по регулярному выражению и замену
    • preg_split — Разбивает строку по регулярному выражению

    preg_grep

    Функция preg_grep — Возвращает массив вхождений, которые соответствуют шаблону

    array preg_grep (string pattern, array input [, int flags])

    preg_grep() возвращает массив, состоящий из элементов входящего массива input, которые соответствуют заданному шаблону pattern.

    Параметр flags может принимать следующие значения:

    PREG_GREP_INVERT
    В случае, если этот флаг установлен, функция preg_grep(), возвращает те элементы массива, которые не соответствуют заданному шаблону pattern.
    Результат, возвращаемый функцией preg_grep() использует те же индексы, что и массив исходных данных. Если такое поведение вам не подходит, примените array_values() к массиву, возвращаемому preg_grep() для реиндексации.
    Пример кода:

    preg_match

    Функция preg_match — Выполняет проверку на соответствие регулярному выражению

    int preg_match ( string pattern, string subject [, array matches [, int flags [, int offset]]]) Ищет в заданном тексте subject совпадения с шаблоном pattern

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

    flags может принимать следующие значения:

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

    Поиск осуществляется слева направо, с начала строки. Дополнительный параметр offset может быть использован для указания альтернативной начальной позиции для поиска. Аналогичного результата можно достичь, заменив subject на substr()($subject, $offset).

    Функция preg_match() возвращает количество найденных соответствий. Это может быть 0 (совпадения не найдены) и 1, поскольку preg_match() прекращает свою работу после первого найденного совпадения. Если необходимо найти либо сосчитать все совпадения, следует воспользоваться функцией preg_match_all(). Функция preg_match() возвращает FALSE в случае, если во время выполнения возникли какие-либо ошибки.

    Рекомендация: Не используйте функцию preg_match(), если необходимо проверить наличие подстроки в заданной строке. Используйте для этого strpos() либо strstr(), поскольку они выполнят эту задачу гораздо быстрее.

    Пример кода

    Пример кода

    Пример кода

    Результат работы примера:

    domain name is: htmlweb.ru

    preg_match_all

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

    int preg_match_all (string pattern, string subject, array matches [, int flags [, int offset]])

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

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

    Дополнительный параметр flags может комбинировать следующие значения (необходимо понимать, что использование PREG_PATTERN_ORDER одновременно с PREG_SET_ORDER бессмысленно):

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

    Пример кода

    Результат работы примера:

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

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

    Пример кода

    Результат работы примера:

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

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

    В случае, если никакой флаг не используется, по умолчанию используется PREG_PATTERN_ORDER.

    Поиск осуществляется слева направо, с начала строки. Дополнительный параметр offset может быть использован для указания альтернативной начальной позиции для поиска. Аналогичного результата можно достичь, заменив subject на substr()($subject, $offset).

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

    Пример кода

    Пример кода

    Результат работы примера:

    preg_quote

    Функция preg_quote — Экранирует символы в регулярных выражениях

    string preg_quote (string str [, string delimiter])

    Функция preg_quote() принимает строку str и добавляет обратный слеш перед каждым служебным символом. Это бывает полезно, если в составлении шаблона участвуют строковые переменные, значение которых в процессе работы скрипта может меняться.

    В случае, если дополнительный параметр delimiter указан, он будет также экранироваться. Это удобно для экранирования ограничителя, который используется в PCRE функциях. Наиболее распространенным ограничителем является символ ‘/’.

    В регулярных выражениях служебными считаются следующие символы: . \\ + * ? [ ^ ] $ ( ) < >= ! | :

    Пример кода

    Пример кода

    Результат работы примера:

    preg_replace

    Функция preg_replace — Выполняет поиск и замену по регулярному выражению

    mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])

    Выполняет поиск в строке subject совпадений с шаблоном pattern и заменяет их на replacement. В случае, если параметр limit указан, будет произведена замена limit вхождений шаблона; в случае, если limit опущен либо равняется -1, будут заменены все вхождения шаблона.

    Replacement может содержать ссылки вида \\n либо (начиная с PHP 4.0.4) $n, причем последний вариант предпочтительней. Каждая такая ссылка, будет заменена на подстроку, соответствующую n’нной заключенной в круглые скобки подмаске. n может принимать значения от 0 до 99, причем ссылка \\0 (либо $0) соответствует вхождению всего шаблона. Подмаски нумеруются слева направо, начиная с единицы.

    При использовании замены по шаблону с использованием ссылок на подмаски может возникнуть ситуация, когда непосредственно за маской следует цифра. В таком случае нотация вида \\n приводит к ошибке: ссылка на первую подмаску, за которой следует цифра 1, запишется как \\11, что будет интерпретировано как ссылка на одиннадцатую подмаску. Это недоразумение можно устранить, если воспользоваться конструкцией \$<1>1, указывающей на изолированную ссылку на первую подмаску, и следующую за ней цифру 1.

    Результатом работы этого примера будет:

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

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

    The bear black slow jumped over the lazy dog.
    Используя ksort(), получаем желаемый результат:

    The slow black bear jumped over the lazy dog.

    В случае, если параметр subject является массивом, поиск и замена по шаблону производятся для каждого из его элементов. Возвращаемый результат также будет массивом.

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

    Модификатор /e меняет поведение функции preg_replace() таким образом, что параметр replacement после выполнения необходимых подстановок интерпретируется как PHP-код и только после этого используется для замены. Используя данный модификатор, будьте внимательны: параметр replacement должен содержать корректный PHP-код, в противном случае в строке, содержащей вызов функции preg_replace(), возникнет ошибка синтаксиса.

    Пример кода: Замена по нескольким шаблонам

    Этот пример выведет:

    Пример кода: Использование модификатора /e

    Пример кода: Преобразует все HTML-теги к верхнему регистру

    preg_replace_callback

    Функция preg_replace_callback — Выполняет поиск по регулярному выражению и замену с использованием функции обратного вызова

    mixed preg_replace_callback (mixed pattern, callback callback, mixed subject [, int limit])

    Поведение этой функции во многом напоминает preg_replace(), за исключением того, что вместо параметра replacement необходимо указывать callback функцию, которой в качестве входящего параметра передается массив найденных вхождений. Ожидаемый результат — строка, которой будет произведена замена.

    Пример кода

    preg_split

    Функция preg_split — Разбивает строку по регулярному выражению

    array preg_split (string pattern, string subject [, int limit [, int flags]])

    Возвращает массив, состоящий из подстрок заданной строки subject, которая разбита по границам, соответствующим шаблону pattern.

    В случае, если параметр limit указан, функция возвращает не более, чем limit подстрок. Специальное значение limit, равное -1, подразумевает отсутствие ограничения, это весьма полезно для указания еще одного опционального параметра flags.

    flags может быть произвольной комбинацией следующих флагов (соединение происходит при помощи оператора ‘|’):

    PREG_SPLIT_NO_EMPTY
    В случае, если этот флаг указан, функция preg_split() вернет только непустые подстроки.

    PREG_SPLIT_DELIM_CAPTURE
    В случае, если этот флаг указан, выражение, заключенное в круглые скобки в разделяющем шаблоне, также извлекается из заданной строки и возвращается функцией. Этот флаг был добавлен в PHP 4.0.5.

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

    Примеры кода

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

    Проблема с вызовом функции внутри preg_replace

    Не работает, $ 1-значение теряется при вызове функции:

    Работает отлично, выходы: stackoverflow.com

    Мне нужно отправить значение $ 1 в зависимости от в preg_replace. Что я делаю не так?

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

    Вам необходимо установить электронный модификатор , чтобы выражение подстановки , которая будет выполнено:

    Обратите внимание, что замена теперь должен быть допустимым выражением PHP. В этом случае выражение будет вычислено для:

    И не забудьте , чтобы избежать вывода, по крайней мере htmlspecialchars :

    Регулярные выражения в PHP

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

    • Все началось в 1940 — 1960-х годах, когда множество умных людей говорили о регулярных выражениях;
    • 1970-е годы g / re / p;
    • 1980 Perl и Генри Спенсер;
    • 1997 PCRE (регулярные выражения, совместимые с Perl). Именно тогда начался взлет того, что мы называем регулярные выражения. PCRE предоставляет библиотеки почти для каждого языка.

    Общее использование регулярных выражений в PHP

    PHP включает в себя три основные функции для работы с PCRE — preg_match , preg_match_all и preg_replace .

    Выражение возвращает 1 , если соответствие установлено, 0 — если нет, и false — если возникает ошибка:

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

    Выражение возвращает замененную строку или массив ( на основе объекта $subject ):

    Общее использование регулярных выражений в JavaScript

    Регулярные выражения в JavaScript выглядят почти так же, как и в PHP .

    Возвращает массив совпадений или null , если совпадений не найдено:

    Регулярное выражение, которое возвращает строку с выполненными заменами:

    Особенности регулярных выражений в JavaScript

    • Точка никогда не соответствует новой строке:
    • Те же методы для сравнения соответствия и замены через регулярное выражение, что и без них.

    Принципы составления шаблонов регулярных выражений

    Рассмотрим пример, в котором нужно найти адреса электронной почты в базе кода. Наша цель: /[w.+-]+@[a-z0-9-]+(.[a-z0-9-]+)*/i

    Регулярные выражения состоят из двух типов символов:

    • специальные символы: []? * + <> () ^ $ / .
    • Литералы.

    Представьте себе входные строки как болты, а шаблон — как набор разъемов для них (в соответствующем порядке).

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

    • Символ обратной косой черты \ может заменять другой специальный символ в регулярном выражении:
    • Точка и w — .

    Совпадение со всеми символами, кроме новых строк. Если хотите проверить на соответствие точке, и только точке — , на соответствие буквам, цифрам и нижнему подчеркиванию — w

    Совпадение с символами внутри скобок. Поддерживает диапазоны. Некоторые примеры:
    o [abc] — соответствует любым a, b или c.
    o [a-z] прописные буквы.
    o [0-9] любая цифра.
    o [a-zA-Z] — соответствует любому буквенному символу в нижнем или верхнем регистре.
    • Опционально ? Соответствие 0 или 1.
    • Звездочка *.

    Звездочка обозначает 0 или более символов.

    Соответствие 1 или более символам.

    Минимальное и максимальное значения. Некоторые примеры синтаксиса регулярных выражений:
    o <1,>не менее 1.
    o <1,3>от 1 до 3.
    o <1,64>от 1 до 64.

    Добавим все это, чтобы получить регулярное выражение для адресов электронной почты:

    Как это выглядит в PHP :

    Использование регулярного выражения для валидации

    Задача : убедиться, что вводимые данные — это то, что мы ожидаем. Цель 1 : /[^[]w$.]/ Цель 2: /^[0-9]<1,2>[dwmy]$/

    Регулярные выражения подходят для поиска элементов, но вам нужно знать, что именно вы ищете.

    Когда не стоит использовать регулярное выражение для проверки?

    Многие случаи лучше обрабатывать с помощью функции PHP filter_var . Например, проверка адреса электронной почты должна выполняться с помощью встроенных фильтров PHP :

    Валидация с помощью регулярных выражений

    Регулярные выражения в конце строки используют анкоры:

    ^ — указывает начало строки.
    $ — знак доллара, который указывает конец строки.

    Исключенные классы символов

    [^abc] — все, кроме a , b или c , включая новые строки.

    Пример, который обеспечивает ввод только буквенно-цифровых символов, тире, точки, подчеркивания:

    Поиск и замена

    Наиболее распространенными функциями PCRE для выполнения поиска и замены являются preg_replace() и preg_replace_callback() . Но есть также preg_filter() и preg_replace_callback_array() , которые делают почти то же самое. Обратите внимание, что функция preg_replace_callback_array() доступна, начиная с PHP7 .

    Заменить слова в списке

    Если в регулярном выражении есть подшаблоны ( в круглых скобках ), можно заменить $N или N ( где N является целым числом > = 1 ), это называется «обратная ссылка».

    Перестановка двух чисел

    Изменение форматирования даты

    Простой пример замены URL-адреса в теге

    Иногда нужно выполнить сложный поиск и замену, например, при фильтрации/проверке перед заменой. В этой ситуации может пригодиться preg_replace_callback() .

    Приведенное в предыдущем примере регулярное выражение может заменить только URL-адреса , начинающиеся с http или https . Но теперь нам также нужно заменить URL-адреса, начинающиеся с www. Кто-то подумает, что можно просто изменить https? : // в подшаблоне. Например, на ( ?: Https? : // | www . ), Но это не будет работать в большинстве браузеров, потому что они будут интерпретировать www.domain как относительный путь.

    Поэтому в конструкторе регулярных выражений перед заменой нужно выполнить некоторые действия, добавив http:// , если URL-адрес начинается с www .

    Проблема : ссылка @mentions и #tags
    Цель : /B@([w]<2,>)/i

    Данная публикация представляет собой перевод статьи « Regex — regular expressions in PHP » , подготовленной дружной командой проекта Интернет-технологии.ру

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

    preg-replace-callback Как распознать токены между повторяющимися разделителями? Открыть

    preg-replace-callback Как закодировать все URL из строки, используя Preg_Replace Открыть

    preg-replace-callback Как мне прекратить разбирать ошибки и заставить работать код в PHP 5 И 7 Открыть

    preg-replace-callback Замените модификатор preg_replace () e на preg_replace_callback Открыть

    preg-replace-callback Замените preg_replace через preg_replace_callback Открыть

    preg-replace-callback Как преобразовать иностранные символы в регулярных выражениях в соответствующий регистр? Открыть

    preg-replace-callback PHP — preg_replace_callback терпит неудачу с вложенными тегами Открыть

    preg-replace-callback Разборное дерево print_r () с PHP 7 (без preg_replace () и / e) Открыть

    preg-replace-callback PHP: использование специальных символов в обфускаторе плохих слов Открыть

    preg-replace-callback Я не понимаю, как работает preg_replace_callback, как обновить с preg_replace Открыть

    preg-replace-callback Регулярное выражение с preg_replace_callback используется для фильтра ненормативной лексики Открыть

    preg-replace-callback PHP заменяет динамический контент на основе позиции в строке Открыть

    preg-replace-callback PHP Match All Character in New Line with Regex Открыть

    preg-replace-callback preg_replace_callback номер 404 в качестве значения Открыть

    preg-replace-callback Вывести HTML с preg_replace_callback не по порядку Открыть

    preg-replace-callback Как преобразовать модификатор preg_replace e в pref_replace_callback Открыть

    preg-replace-callback Кто-нибудь знает, почему это не работает? Работа с: preg_replace (): модификатор / e больше не поддерживается, используйте preg_replace_callback instea Открыть

    preg-replace-callback Предупреждение: preg_replace_callback (): требуется аргумент 2 Открыть

    preg-replace-callback используйте preg_replace_callback с массивом Открыть

    preg-replace-callback Как я могу найти строку на основе определенных критериев и заменить определенное значение с помощью регулярных выражений Открыть

    preg-replace-callback Разрешить запись в массив в PHP preg_replace_callback Открыть

    preg-replace-callback Что делает implode в шаблоне, используемом для preg_replace_callback? Открыть

    preg-replace-callback Как получить шаблон, который соответствует строке на основе порядка строк Открыть

    preg-replace-callback Подобный текст без потери форматирования текста Открыть

    PHP preg_replace_callback: почему не срабатывает функция?

    Пытаюсь обернуть содержимое параграфов из переменной $text , элементом i .

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

    . но, это регулярное выражение валится с ошибкой: Warning: preg_replace_callback(): Compilation failed: lookbehind assertion is not fixed length at offset 16 in.

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

    Почему не срабатывает это регулярное выражение именно с функцией preg_replace_callback ? И есть ли еще какая-либо возможность в регулярных выражениях, вытащить содержимое элемента параграфа и обработать только его?

    Функция preg_replace_callback_array()

    В PHP 7 появилась функция preg_replace_callback_array() . Я её использовал в последнем проекте. Хочется показать на простых примерах, как она работает. Для этого разберём и другие функции. Для понимания статьи нужно знать, как работают регулярные выражения.

    Давайте напишем небольшой интерпретатор некоторых BB-кодов.

    Замена по одному выражению

    Начнём с простой замены: [b] → ( здесь и далее с учётом пробелов и переносов, то есть варианты типа [ b ] тоже сработают). Для удобства основные символы выделены жёлтым цветом.

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

    Замена по нескольким выражениям

    Можно указать несколько шаблонов и их замен: [b] → , [/b] → . Шаблоны и их замены теперь находятся в массиве ( для работы с открывающими и закрывающими тегами можно было бы просто написать (\ / ?) , но мы так делать не будем, чтобы продемонстрировать возможности этого семейства функций).

    Можно усложнить выражение, чтобы учитывать разные теги: [b] → , [/b] → , [i] → , [/i] → .

    Знак $1 означает первую найденную часть подстроки, обозначенную круглыми скобками.

    Замена с обработкой

    Но пока ещё нельзя было как-то модифицировать найденные выражения ( например, менять регистр), можно было только подставить найденную часть подстроки как есть. Функция preg_replace_callback() , один из аргументов которой — функция обратного вызова ( callback), позволяет это сделать. Хоть пока и только с одним регулярным выражением. Функция обратного вызова срабатывает для каждого найденного шаблона.

    Получаются следующие замены: [b] , [B] → ; [i] , [I] → .

    Замена с обработкой по нескольким выражениям

    Функция preg_replace_callback_array() позволяет делать то же самое, что и preg_replace_callback() , но с несколькими регулярными выражениями. Замены: [b] , [B] → ; [/b] , [/B] → ; [i] , [I] → ; [/i] , [/I] → .

    Детали работы этой и других функций ( максимальное количество замен для шаблонов и подсчёт количества произведённых замен) читайте в официальной документации.

    Замена может быть сколь угодно сложной. Например, в моём проекте ссылки на статьи формируются по неким правилам. Это может быть просто адрес статьи: << url >> . Или адрес раздела и адрес статьи ( должен существовать внешний ключ): << section_id ->name >>/<< url >> . Можно взять только часть поля ( к примеру, год из метки времени 2020-08-28 — это первые четыре символа): << date_and_time | 0. 3 >> . Во втором случае без внешних данных не обойтись, поэтому используем лямбда-функцию как замыкание ( closure), захватив некую переменную по ссылке.

    Илон Маск рекомендует:  Что такое код asp httpredirect
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL