Понимание регулярных выражений PHP


Оглавление (нажмите, чтобы открыть):

Популярные примеры работы регулярных выражений в PHP

Вопросов по данной теме уйма. И я решил создать свою подборку регулярных выражений. Думаю многим поможет!

Для справки.
. — (точка) соответствует любому символу.
<> — (фигурные скобки) нужны для обозначения количества необходимых символов. Например, w <3>— три буквы w подряд. Также есть диапозон z<2,5>, то есть z может повторяться от 2 до 5 раз.
| — (вертикальная черта) логическое или в регулярных выражениях.
\n — перевод строки
\r — так же перевод строки
\t — табуляция
\d — цифра
\D — только не цифра
\s — пробел
\S — только не пробел
\w — все буквы, цифры и знак подчеркивания «_»
\W — только не буква, цифра или подчеркивание
Модификаторы в конце выражения
/i — делает поиск по выражению регистронезависимым. Нет разницы между заглавным и прописным символом
/U — модификатор указывает на то, что результатом поиска должен быть самый короткий отрывок, удовлетворяющий маске поиска. Рекомендую всегда использовать данный модификатор
/m — этот модификатор позволяет искать отрезок текста только внутри одной строки
/s — поиск идёт всему тексту, не обращая внимания на переносы строк
/x — игнорируются пробельные символы, в том числе символы табуляции и перевода строки

Примеры preg_replace PHP

1. Удаляем определённую ссылку в переменной text

2. Удаляем комментарии в переменной text

3. Удаляем спецсимволы

4. Удаляем всё, что между

5. Удаляем всё, что между

6. Удаляем конкретные символы из строки

7. Удаляем пробелы по бокам строки и обычные пробелы

8. Удаляем лишние переводы строк и переносы

9. Удаляем расширения в названиях файлов

10. Создаём функцию обработки текста

11. Найти содержимое определённого тега и вставить его в другие теги

12. Удаляем многократно повторяющиеся знаки препинания (например, . или . )

13. Добавить или убрать текст в начале или конце переменной с текстом

14. Находим все http:// и заменяем на ссылки

15. Удаление GET-параметров из URL

16. Добавить тег br в начало или конец строк

17. Как конвертировать html в текст

18. Как разобрать email и сделать ссылку

Примеры preg_match PHP

1. проверка mail адреса на корректность

2. Найти mail адреса в тексте

3. Является ли переменная числом, длиной от 13 до 16 символов (проверка кредитной карты)

4. Проверка имени файла

Программы (exe, xpi, . )

Изображения (jpg, png, . )

5. Ищем в тексте мобильные телефоны РФ

6. Состоит ли строка только из букв, цифр и _, длиной от 8 до 20 символов:

7. Есть ли в строке идущие подряд символы, не менее 3-х символов подряд (типа абвгДДДеё, но не ааббаабб):

8. Поиск в разных частях строки конструкции:

9. Проверки на тип браузера. Возвращает true если browser = Netscape 2, 3 or MSIE 3.

Примеры ereg PHP

1. Проверка mail адреса в тексте

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

Заметка о регулярных выражениях. Зачем они нужны, где используются и как их применять. Иными словами о поиске в PHP.

Использование регулярных выражений в функциях PHP, замены preg_replace, поиска preg_match.

Например, рассмотрим такую функция:

То что внутри этой функции, все эти на первый взгляд непонятные значения, называется регулярным выражением (PHP RegEx). Они используются для поиска конкретных данных.

Шаблон (символы) поиска берет своё начало с языка Perl.

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

Метасимволы — определяют группу обычных символов. Модификаторы — помогают понять сколько и какое количество этих символов искать.

Метасимволы регулярного выражения

Значения некоторых метасимволов из примера выше (также они будут встречаться ниже):

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

Ещё модификаторы, но не используются в текущих примерах:

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

Дополнительные опции

Кроме модификаторов и метасимволов есть опции (приведены не все):

Опции могут сочетаться вместе:

Шаблоны

Также существуют шаблоны, что-то вроде аналога метасимволов, один из них:

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

Эксперименты

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

Также читайте

Привет. Ты находишься на моём сайте. Я разработчик. Здесь я делюсь своими наработками и знаниями. Спрашивай в комментариях, если тебе что-то не понятно или пиши, если есть что добавить.

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

15 регулярных выражений PHP в помощь веб-разработчику

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

Регулярное выражение Означает
foo
^foo Строка начинается с “foo”
foo$ Строка заканчивается на “foo”
^foo$ «foo» встречается в строке только один раз
[abc] a, b, или c
[a-z] любой символ в нижнем регистре
[^A-Z] любой символ, не находящийся в верхнем регистре
(gif jpg)
[a-z]+ Один или более символов нижнего регистра
[0-9.-] Любая цифра, точка или знак минус
^[a-zA-Z0-9_]<1,>$ Любое слово, хотя бы одна буква, число или _
([wx])([yz]) wy, wz, xy, или xz
(^A-Za-z0-9) Любой символ (не число и не буква)
([A-Z]

[0-9]<4>)

PHP-функции для регулярных выражений

Функция Описание
preg_match() Функция preg_match() ищет строку по заданному шаблону, возвращает true, если строка находится и false, в остальных случаях
preg_match_all() Функция preg_match_all() находит все вхождения строки, заданной по шаблону
preg_replace() Функция preg_replace(), действует по тому же принципу, что и ereg_replace(), за исключением того, что регулярные выражения можно использовать как для задания шаблона поиска, так и для строки, на которую следует заменить, найденное значение.
preg_split() Функция preg_split(), действует так же как split(), за исключением того, что регулярное выражение можно использовать в качестве параметра для шаблона поиска.
preg_grep() Функция preg_grep() ищет все элементы входного массива, возвращая все элементы, соответствующие шаблону регулярного выражения.
preg_quote() Экранирует символы регулярного выражения

Проверка доменного имени

Проверяем, является ли строка правильным доменным именем

Подсветка слова в тексте

Это очень полезное регулярное выражение, с его помощью вы можете найти нужное слово и подсветить его. Особенно полезно для отображения результатов поиска.
?

Подсветка результатов поиска в WordPress блоге

Как уже говорилось в предыдущем примере, этот пример кода, удобно использовать в выдаче поисковых результатов и есть отличный способ внедрить эту функцию в wordpress-блог.
Откройте ваш файл search.php, и найдите функцию the_title(). Замените ее следующим кодом:
[PHP]1
echo $title;
Теперь, выше этой строки, добавьте этот код:
?

\0‘,
$title);
?>
Сохраните файл search.php, и откройте style.css. Добавьте следующую строку:

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

Если вам когда-нибудь требовалось получить все картинки с веб-страницы, этот код должен быть Вы легко сможете создать загрузчик изображений с помощью возможностей cURL

Удаление повторяющихся слов (не чувствителен к регистру)

Во время печатания, часто повторяются слова? Поможет это регулярное выражение.

Удаление повторяющейся пунктуации

То же самое, только для пунктуации. Попрощайтесь с двойными запятыми.

Поиск XML/HTML тэгов

Эта простая функция, принимает два аргумента. Первый – это тэг, который вам нужно найти, и второй – это переменная, содержащая XML или HTML. Повторюсь, эту функцию очень удобно использовать вместе с cURL.

Поиск XHTML/XML тэгов с определенным значением атрибута

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

Поиск шестнадцатеричных значений цветов

Еще один полезный инструмент для веб-разработчика! Он позволяет вам находить/проверять шестнадцатеричные значение цвета.

Поиск заголовка статьи

Этот фрагмент кода найдет и выведет на экран текст, находящийся внутри тэгов , на html-странице.

Парсинг логов Apache

Большинство сайтов запущено на всем известном веб-сервере Apache. Если ваш сайт находится в их числе, почему бы не использовать PHP и регулярные выражения для разбора логов апача?

амена двойных кавычек “умными” кавычками

Если вы любитель типографики, вам понравится это регулярное выражение, заменяющее обычные двойные кавычки, на “умные кавычки”. Похожее регулярное выражение используется в wordpress в контенте страницы.
?
1
preg_replace(‘B»b([^»x84x93x94rn]+)b»B’, ‘?1?’, $text);
Комплексная проверка пароля

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

WordPress: Использование регулярного выражения для получения картинок из записи

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


Генерация автоматических смайлов

Другая функция, используемая в wordpress – позволяет автоматически заменять символы смайлов на картинку смайла.

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

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

помогите понять, что значат в этом выражении эти все знаки.
Например — ]* — как это понять? или (.*) — что это? и почему в массиве $images будут именно ссылки, а не полностью весь элемент
Ну и собственно как сделать регулярное выражение, чтобы получать такие же ссылки из тега
. или как получить содержимое всего элемента

  • Вопрос задан 07 мар.
  • 67 просмотров

помогите понять, что значат в этом выражении эти все знаки.

Часть 2. Как обрабатывать текст в PHP

Использовать регулярные выражения в PHP легко: — просто дайте волю своей жадности, лени и зависти

Серия контента:

Этот контент является частью # из серии # статей: Использование регулярных выражений в PHP

Этот контент является частью серии: Использование регулярных выражений в PHP

Следите за выходом новых статей этой серии.

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

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

В действительности сложность создания приложения прямо пропорциональна преобразованиям, которые оно выполняет. Гостевая книга Web-сайта, передающая имя и адрес в поля базы данных, устроена элементарно. С другой стороны, онлайновый магазин, который передает большое количество видов информации в модель данных коммерческой сделки и преобразует данные в информацию для реализации процесса принятия решений, достаточно сложен с точки зрения разработки. Искусство программирования заключается в умелом манипулировании данными и информацией — мастерство, схожее с фиксацией света в живописи.

Как было сказано в первой части, регулярные выражения являются одним из самых мощных средств манипулирования данными. Регулярные выражения лаконично описывают форму данных и раскладывают их на составляющие. Например, следующее регулярное выражение можно использовать для обработки температуры, заданной в градусах по Цельсию или по Фаренгейту: /^([+-]?[0-9]+)([CF])$/ .

Регулярное выражение сравнивает начало строки (отображается знаком «крышка» ( ^ ), за которым идет знак «+», знак «-«, или ничего ( [+-]? ), за которым следует целое число ( [0-9]+ ), обозначение шкалы — Цельсия или Фаренгейта ( [CF] ) — и заканчивается концом строки (обозначается знаком доллара $ ).

В данном регулярном выражении операторы начала строки и конца строки представляют собой примеры операторов нулевой ширины или совпадений по положению, а не по символам. Круглые скобки также не указывают на символы. Зато, если заключить шаблон в круглые скобки, то будет извлечен текст, соответствующий шаблону. Следовательно, если текст полностью сопоставим с шаблоном, то первая пара круглых скобок выдаст строку, представляющую собой положительное или отрицательное целое число, например, +49, а вторая пара круглых скобок — или букву C, или F.

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

Круглые скобки опять приходят на помощь

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

Приведу пример. Догадаетесь, какому типу данных соответствует данное выражение?

Как можно догадаться, это регулярное выражение определяет имена Интернет-сайтов (только для доменов .com, .edu, и .info). Отличием является использование дополнительного оператора ?: . Квалификатор части шаблона ?: отключает функцию извлечения данных, и тем самым дает круглым скобкам возможность обозначать последовательность действий. Например, в данном случае фраза (?:\.[-a-z0-9]+)* соответствует нулю или более элементам строки, например, «.ibm.» Аналогично, фраза \.(?:com|edu|info) обозначает последовательность символов, за которой идет одна из строк com , edu , или info .

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

Примечание: Модификатор i в конце регулярного выражения делает все сопоставления с шаблоном нечувствительными к регистру. Следовательно, подмножество a-z будет сопоставимо со всеми буквами, независимо от регистра.

В PHP есть и другие модификаторы частей шаблона (subpattern). Используя отладчик регулярных выражений, показанный в первой части данной серии (повторно показан в листинге 1), попробуйте сопоставить регулярное выражение ((?i)edu) со строками «EDU,» «edu,» и «Edu.» Если в начале части шаблона задать модификатор (?i) , то сопоставление с шаблоном не будет зависеть от регистра. Чувствительность к регистру восстанавливается, как только заканчивается данная часть шаблона. (Сравните с модификатором / . /i , который применяется ко всему шаблону.)

Листинг 1. Простой отладчик регулярных выражений

Еще один полезный модификатор части шаблона — это (?x) . Он позволяет добавлять в шаблон пробелы, что упрощает чтение регулярных выражений. Таким образом, часть шаблона ((?x) edu | com | info) (обратите внимание на пробелы между операторами дизъюнкции, которые добавлены для удобочитаемости) аналогична (edu|com|info) . Для того, чтобы добавлять пробелы и комментарии в регулярное выражение, можно использовать глобальный модификатор / . /x , см. листинг ниже.

Листинг 2. Добавление пробелов и комментариев

Как видно из листинга, при необходимости модификаторы можно объединять. Если необходимо включить в регулярное выражение символ пробела при использовании модификатора (?x) , используйте метасимвол \s для поиска любого пробельного символа и \ (обратный слеш с пробелом) для поиска одного пробела, например, ((?x) hello \ there) .

Оглядываемся вокруг

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

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

Вот пример полезного применения форматирования. Предположим, что Web-форма передает приложению значение зарплаты с округлением до целого доллара. Так как зарплата хранится в виде числа целого типа, то перед сохранением переданных данных приложение должно удалять из них знаки пунктуации. Однако при извлечении данных из хранилища, возможно, понадобится изменить их формат и сделать удобочитаемыми с помощью разделителей. В листинге 3 показано, как простой PHP-запрос преобразует сумму в долларах в число.

Листинг 3. Преобразование суммы в долларах в число

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

А теперь давайте выполним обратную операцию — добавим к числу знак денежной единицы и запятые-разделители сотен, тысяч и миллионов. Для добавления запятых в определенных позициях можно написать программу для поиска этих компонентов, а можно воспользоваться операторами посмотри вперед и посмотри назад. Модификатор части шаблона ? обозначает посмотри назад (то есть влево) от текущей позиции. Модификатор ?= означает «посмотри вперед» (то есть вправо) от текущей позиции.

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

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

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

Листинг 4. Пример использования оператора «посмотри вперед» («предвидение»)

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

Это регулярное выражение при каждом обнаружении запятой (на это указывает запятая в самом начале регулярного выражения) проверяет утверждение: «Впереди не было кавычек или было четное количество кавычек». Если утверждение верно, то запятую можно заменить знаком табуляции (the \t ).

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

Листинг 5. Добавление запятых

Давайте пройдем по коду. Сначала параметр зарплаты очищается от знаков пунктуации для моделирования ситуации чтения целого числа из базы данных. Затем выполняется цикл в поисках позиций, где за одним числовым символом ( (\d) идут три числовых символа ( (\d\d\d\) : если обнаруживается граница слова, заданная как \b , цикл прекращается. Граница слова — это еще один оператор нулевой ширины, который соответствует следующим позициям:

  • Перед первым символом строки, если это буква слова.
  • За последним символом строки, если это буква слова.
  • Между буквой слова и небуквенным символом, непосредственно за буквой слова.
  • Между небуквенным символом и буквой слова, непосредственно за небуквенным символом.

Таким образом, примерами правильных границ слова являются пробел, точка и запятая.

Благодаря внешнему циклу регулярное выражение перемещается слева направо в поисках цифры, за которой идут три цифры и граница слова. При обнаружении совпадения между двумя частями шаблона добавляется запятая. Цикл должен продолжаться до тех пор, пока оператор preg_replace() находит совпадения, что задано в условии $old != $pretty_print .

Жадность и лень

Регулярные выражения обладают большими возможностями, иногда даже слишком большими. Например, давайте рассмотрим, что произойдет, если регулярное выражение «.*» будет обрабатывать строку «The author of ‘Wicked’ also wrote ‘Mirror, Mirror.'» Вероятно, вы предполагаете, что preg_match() вернет два совпадения, и с удивлением обнаружите, что результат всего один: ‘Wicked’ also wrote ‘Mirror, Mirror.’

Почему? Если не задать иное, то такие операторы как * (ноль или более) и + (один или более) — «жадные». Если сопоставление с образцом может продолжаться, то они и будут его продолжать до тех пор, пока не будет возвращен максимальный результат из возможных. Для сохранения минимальных совпадений необходимо принудительно заставлять определенные операторы быть «ленивыми». «Ленивые» операторы находят самое короткое совпадение и на этом останавливаются. Чтобы сделать оператор более «ленивым», добавьте суффикс в виде знака вопроса. Пример показан в листинге 6.

Листинг 6. Добавление суффикса в виде знака вопроса

Приведенный фрагмент кода дает:

Регулярное выражение «.*?» расшифровывается следующим образом: «найти кавычку, за которой идет ровно столько символов с последующей кавычкой.

Однако иногда оператор * может быть слишком «ленивым». Например, посмотрите на следующий фрагмент кода. Что он делает?

Листинг 7. Простой отладчик регулярных выражений

Что вы загадали? «123»? «1»? Нет результата? На самом деле результатом будет Array ( [0] => [1] => ) , означающий, что совпадение было найдено, но никаких данных извлечено не было. Почему? Вспомните, что оператор * ищет совпадения с нулем или более символов. В данном случае, выражение [0-9]* находит совпадение с нулем символов от начала строки, и обработка заканчиваетс.

Для решения данной проблемы добавьте оператор нулевой ширины для привязки совпадения, который заставляет регулярное выражение продолжать сопоставления; /([0-9]*\b/ .

Советы и рекомендации

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

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

Вам уже знакомы метасимволы, например, \s — соответствует любому пробельному символу. Кроме того, большинство реализаций регулярных выражений поддерживает предопределенные классы символов, которые более просты в использовании и переносимы с одного письменного языка на другой. Например, класс символов [:punct:] замещает все символы пунктуации в данном языке. Вместо [0-9] можно использовать [:digit:] и более переносимое замещение [:alpha:] вместо [-a-zA-Z0-9_] . Например, можно убрать все знаки пунктуации, используя:

Класс символов представляет собой более сжатую форму по сравнению с подробным описанием всех символов пунктуации. Полный перечень классов символов можно найти в документации по версии языка PHP.

Как исключить то, что вы не ищете

Как показано в примере с данными, разделенными символом табуляции, в качестве значений, разделенных запятыми (CSV), иногда проще и точнее задать список тех вариантов, которые не нужно находить (сопоставлять). Последовательность, начинающаяся со знака «крышка» ( ^ ) будет соответствовать любому символу, не принадлежащему данной последовательности. Например, для проверки правильности телефонных номеров для США можно использовать регулярное выражение /[2-9][0-9]<2>[2-9][0-9]<2>[0-9]<4>/ . Используя набор ограничений можно написать регулярное выражение в более явном виде /[^01][0-9]<2>[^01][0-9]<2>[0-9]<4>/ . Оба регулярных выражения работают, хотя смысл последнего, вероятно, более понятен.

Пропуск новой строки

Если во входных данных несколько строк, стандартного регулярного выражения будет недостаточно, так как сканирование прекращается на начале новой строки, которая обозначается $ . Однако, если воспользоваться модификаторами s или m , то регулярное выражение будет обрабатывать входные данные по-другому. Первый модификатор рассматривает строковую последовательность как одну строку, где точка указывает на начало новой строки (обычно она этого не делает). Второй рассматривает строковую последовательность как несколько строк, где ^ и $ соответствуют началу и концу любой строки, соответственно. Приведем пример. Если задать $string = «Hello,\nthere»; , то оператор preg_match( «/.*/s», $string, $matches) параметру $matches[0] присвоит значение Hello,\nthere . (При удалении s будет выдано Hello .)

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

Ресурсы для скачивания

Похожие темы

  • Оригинал статьи: «Mastering regular expressions in PHP, Part 2: How to process text in PHP» (EN).
  • PHP.net — ведущий ресурс для PHP-разработчиков (EN).
  • Познакомьтесь с «Рекомендательным списком литературы по PHP» (EN).
  • Повысьте свою квалификацию в области разработок на PHP с помощью раздела Ресурсы с PHP-проектами на сайте developerWorks (EN).
  • Интересные интервью и обсуждения для разработчиков ПО представлены в разделе Подкасты на developerWorks (EN).
  • Работаете с базами данных и PHP? Обратите внимание на Zend Core для IBM — легко устанавливаемую среду для разработки и производства ПО на PHP, поддерживающую IBM DB2 V9 (EN).
  • В разделе Open source на сайте developerWorks можно найти исчерпывающую практическую информацию, инструментальные средства и обновления продуктов, которые помогут вам в разработке с помощью технологий с открытым исходным кодом и использовании их совместно с другими продуктами IBM (EN).
  • Внесите новшества в свой следующий проект по разработке ПО с открытым исходным кодом с помощью ознакомительных версий ПО IBM, которую можно скачать или заказать на DVD-диске (EN).
  • Загрузите ознакомительные версии продуктов IBM и воспользуйтесь средствами разработки приложений и связующим ПО DB2®, Lotus®, Rational®, Tivoli®и WebSphere® (EN).

Комментарии

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


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

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

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

strpos() — Возвращает подстроку в строке.
substr() -Возвращает заданный участок строки.
strcmp() — Сравнивает две строки.
str_replace() — Заменяет в строке все вхождения одной подстроки на другую подстроку.
explode() – разбивает строку в массив по заданному разделителю
strip_tags() — Удаляет из строки все HTML тэги.
strtolower() – Перевод в нижний регистр.
strtoupper() – Перевод в верхний регистр.
trim() — Удаляет (» «, \n, \r, \t) символы в начале и в конце строки.
HtmlSpecialChars() — Заменяет специальные символы на их HTML эквиваленты.
convert_cyr_string() — Преобразует русский текст из одной кодировки в другую.

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

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

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

Предположим, у нас имеется строка:

Если применить к этой известной скороговорке регулярное выражение вида:

то мы получим три слова соответствующих данному шаблону: “Клары” , “Клара” , и “кларнет” .

На первый взгляд, запись регулярного выражения выглядит устрашающе, но как говорится: «Не так страшен черт, каким его малюют!».

Сейчас я вам объясню принцип формирования шаблона для регулярного выражения.

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

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

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

Откинув из нашего выражения разделители и служебные модификаторы, мы получим чистый шаблон регулярного выражения:

Под действие данного шаблона попадут все подстроки в тексте, которые отвечают следующим правилам:

  1. Подстрока начинается с последовательности букв “К”, ”л”, “а”, “р” .
  2. Подстрока заканчивается одним пробельным символом \s .
  3. Между последовательностью “К”, ”л”, “а”, “р” и пробелом \s могут встретиться любые символы .* , также их может не быть вовсе ? .

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

Пришло время, перейти к практическому применению полученных знаний. Рассмотрим несколько полезных примеров регулярных выражений на PHP , но сначала скажем пару слов о функциях preg_match и preg_match_all, используемых в PHP при работе с регулярными выражениями.

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

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

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

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

Советую поэкспериментировать с изменением шаблона, попробуйте например, заключить в квадратные скобки последовательность букв ”л”, “а”, “р” .

В этом случае, получим массив:

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

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

Таблица метасимволов

Метасимвол Значение
\d Цифра (0-9)
\D Не цифра (любой символ кроме символов 0-9).
\s Пустой символ (обычно пробел и символ табуляции).
\S Непустой символ (все, кроме символов, определяемых метасимволом \s).
\w Все буквы, все цифры и знак подчеркивания (‘_’).
\W Все, кроме символов, определяемых метасимволом \w.
\n Символ перевода строки.
\r Символ возврата каретки.
\t Символ табуляции
\xhh Вставка символа с шестнадцатиричным кодом 0xhh, например \x41 вставит латинскую букву ‘A’.
^ Начало строки.
$ Конец строки.
| Метасимвол выбора.
* Ноль или более символов.
+ Одно или более символов.
? Встречается один раз, либо ноль.
<> Квантификатор, указывает количество повторений метасимволов. <4,6>(От 4 до 6 повторений).
\A Начало строки.
\Z Конец строки.
\z Конец текста.
\b Граница слова.
\B Не граница слова.
\G Предыдущий успешный поиск.

Таблица модификаторов

Модификатор Описание
i Шаблон становится регистронезависимым
m Метасимволы ‘^’ и ‘$’ указывают на начало и конец каждой строки а не всего текста.
s Метасимвол ‘.’ включает в свое определение перевод строки.
u Делает все количественные метасимволы «не жадными» .

Таблица примитивных полезных шаблонов

Шаблон Описание
[0-9A-Fa-f] Цифра в шестнадцатеричной системе счисления.
[02468] Четная цифра.
[^\d] Все, кроме цифр.
/\d\d\d/ Трехзначное число.
[^-0-9] Любой символ, кроме минуса и цифры.
/^[a-zA-Z0-9]+$/ Строка состоящая только из букв латинского алфавита и цифр.
[^\s] Все что не пробел.
[^\s.] Все что не пробел и не точка.
foo$ Строка заканчивается на “foo”.
(gif|jpg) Означает как “gif” так и “jpeg”.
^[a-zA-Z0-9_]<1,>$ Любое слово, хотя бы одна буква, число или “_”.
(^A-Za-z0-9) Любой символ (не число и не буква).
/b(word)b/ выбор из строки слова “word”.

Таблица сложных и полезных шаблонов

Шаблон Описание
/^(http|https|ftp)://([A-Z0-9][A-Z0-9_-]*(. [A-Z0-9][A-Z0-9_-]*)+):?(d+)?/?/i Проверка доменного имени.
/A(?=[-_a-zA-Z0-9]*?[A-Z])(?=[-_a-zA-Z0-9]*?[a-z])(?=[-_a-zA-Z0-9]*?[0-9])[-_a-zA-Z0-9]<6,>z/ Комплексная проверка пароля. Строка не менее шести символов, цифры, дефисы и подчеркивания, как минимум один символ верхнего регистра, один нижнего регистра и одна цифра.
[\.\-_A-Za-z0-9]+?@[\.\-A-Za-z0-9]+?[\ .A-Za-z0-9]

Проверка правильности email.
/ (.*) / Поиск заголовка страницы.
^\d<1,2>([-. /])\d<1,2>\1\d<2,4>$ Разбиваем дату на числа.
(?:8|\+7)? ?\(?(\d<3>)\)? ?(\d<3>)[ -]?(\d<2>)[ -]?(\d<2>) Номер мобильного телефона.
/.*?\./ Получить расширение файла.
/\.(?:exe|msi|dmg|bin|xpi|iso)$/i Проверка расширения файла.
/]*href=[\’»]([^\’»]+)[\’»][^<>]*>(((?!/si Внешние ссылки.
/^[0-9]<1,55>$/ Является ли строка числом до 55 цифр.
/([a-zA-Zа-яА-Я]+)/ Разбирает текст на отдельные слова.
/^.<1,10>$/ Любая строка, содержащая от 1 до 10 символов.
/(.*)/ Произвольная последовательность символов, заключенная между тегами.

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

Пример регулярного выражения в php

Пример проверки e-mail с помощью регулярных выражений. Очень часто появляется потребность использовать вот такую проверку:

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

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

Основные функции для работы с Perl-совместимыми регулярными выражениями:

preg_match(pattern, string, [result, flags]) и preg_match_all(pattern, string, result, [flags]), где:

  • pattern – шаблон регулярного выражения;
  • string – строка, в которой производится поиск;
  • result – содержит массив результатов (нулевой элемент массива
    содержит соответствие всему шаблону, первый – первому «захваченному» подшаблону и т.д.);
  • flags – необязательный параметр, определяющий то, как упорядочены результаты поиска.

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

Аналогом preg_match является булева функция POSIX-расширения ereg(string pattern, string string [, array regs]).
Функция ereg() возвращает TRUE, если совпадение найдено, и FALSE – в противном случае.

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

Синтаксис регулярных выражений

Регулярное выражение представляет собой строку. Эта строка состоит из собственно регулярного выражения (шаблона), выделенного с помощью специального символа разделителя (это могут быть символы «/» , «|», «<«, «!» и т.п ) и модификатора, влияющего на способ обработки РВ.

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

Одним из основных метасимволов является обратный слэш «\». Он меняет тип символа, следующего за ним, на противоположный, т.е. если это был обычный символ, то он МОЖЕТ превратиться в метасимвол, если это был метасимвол, то он теряет свое специальное значение и становится обычным символом (это нужно для того, чтобы вставлять в текст специальные символы как обычные).
Например, символ d в обычном режиме не имеет никаких специальных значений, но \d есть метасимвол, означающий «любая цифра». Символ «.» в обычном режиме означает «любой единичный символ», а «\.» означает просто точку.

Другое назначение обратного слэша – кодирование непечатных символов, таких как:

  • \n – cимвол перевода строки;
  • \e – символ escape;
  • \t – cимвол табуляции;
  • \xhh – символ в шестнадцатеричном коде, например \x41 есть буква A и т.д.

Еще одно назначение обратного слэша – обозначение генерируемых символьных типов, таких как:

  • \d – любая десятичная цифра (0-9);
  • \D – любой символ, не являющийся десятичной цифрой;
  • \s – любой пустой символ (пробел или табуляция);
  • \S – любой символ, не являющийся пустым;
  • \w – символ, используемый для написания Perl-слов (это буквы, цифры и символ подчеркивания), так называемый «словарный символ»;
  • \W – несловарный символ (все символы, кроме определяемых \w).

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

Пример использования приведенных выше метасимволов:

Это РВ означает: трехзначное число, за которым следует подстрока plus, любая цифра, затем is и слово из трех словарных символов.

В частности, данному РВ удовлетворяют строки: «123 plus 3 is sum», «213 plus 4 is 217».

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

  • 1. Символьный класс [абвгд] задает один из символов а, б, в, г, д, а; класс [^абвгд] задает любой символ, кроме а, б, в, г, д.
  • 2. Если написать [2бул]ки], то это выражение интерпретируется как один из символов 2, б, у, л, за которым следует строка ки], потому что первая встретившаяся закрывающая квадратная скобка (разбор происходит слева направо) заканчивает определение символьного класса. То есть это РВ совпадет с одной из строк 2ки], бки], уки] или лки].
  • 3. С помощью РВ [0-9А-Яа-я] можно задать любую букву или цифру.

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

0. Пусть дан такой текст, записанный в виде строки:
$str = «11 aaa bbb «.
«ccc 22 ddd «.
«eee ggg 33»;

Метасимволы, распознаваемые ВНУТРИ квадратных скобок:

  • \ — Переходный символ со множеством назначений
  • ^ — Отрицание класса, но только если это первый символ (например, «^\d» задает все, кроме цифр)
  • — Задает диапазон символов (например, «0-9» задает все цифры, «A-Z» – все латинские буквы)
  • ] — Вычисляет символьный класс

Регулярное выражение /\d\d/m может быть сопоставлено следующим подстрокам: 11, 22, 33. Если в начале РВ стоит ^, то совпадения ищутся в начале строки, поэтому выражение /^\d\d/m найдет только 11.

Когда в конце РВ стоит знак доллара $, поиск производится в конце строки, поэтому выражение /\d\d$/m найдет только 33.

Шаблону же /^\d\d\d$/ будет удовлетворять строка, целиком состоящая из трехзначного числа (т.е. она и начинается и заканчивается этим числом).

1. Найдем все html-теги, расположенные в начале каждой строки файла 1.htm.

Шаблон «!^ !mU» ограничен восклицательными знаками. Первая «^» значит, что мы ищем совпадения в начале строк, потом идет символ « ». Таким образом, выделяются все теги в начале строк.

Метасимволы, распознаваемые ВНЕ квадратных скобок:

  • \ — Переходный символ со множеством назначений
  • ^ — Объявляет начало объекта (или строки в многострочном режиме). То есть этот символ определяет, что искомый текст должен находиться в начале строки. Альтернатива: «\A»
  • $ — Объявляет конец объекта (или строки в многострочном режиме). То есть этот символ определяет, что искомый текст должен находиться в конце строки. Альтернативы: «\Z», «\z»
  • . — Совпадает с любым символом, кроме символа перевода строки (по умолчанию)
  • [ — Начинает определение символьного класса
  • ] — Заканчивает определение символьного класса
  • | — Разделяет перечисление альтернативных вариантов
  • ( — Начинает подшаблон регулярное (подвыражение)
  • ) — Заканчивает подшаблон
  • ? — Расширяет значение «(», квантификаторов 0 или 1, и квантификатор минимизации
  • * — 0 или больше повторений (квантификатор)
  • + — 1 или больше повторений (квантификатор)
  • <— Начинает минимальный/максимальный квантификатор
  • > — Заканчивает минимальный/максимальный квантификатор

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

Примеры использования метасимволов ( | и .)

1. Пусть имеется некий текст. Нам нужно найти всех упомянутых в нем людей со званиями.

Метасимвол прямая черта « | » позволяет задавать альтернативные варианты. В примере мы хотели найти всех профессоров или доцентов. Для этого было создано подвыражение «(профессор|доцент)». После звания через пробел фамилия человека, которому оно принадлежит, – для этого существует комбинация «\s[А-Я][А-Яа-я]+». После фамилии идет либо опять пробел, либо точка, если это конец предложения. Получаем опять два альтернативных варианта: «(\s|\.)» (здесь точка экранируется обратным слэшем, чтобы она понималась как обычная точка, без специального значения).

Подвыражения (подшаблоны)

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

1. Локализует множество альтернатив.
Например, шаблон
жар(кое|птица|)

совпадает с одним из слов «жаркое», «жарптица» и «жар». Тогда как без скобок это было бы «жаркое», «птица» и пустая строка.

2. Устанавливает подшаблон как «захватывающий» подшаблон. Это значит, что, когда какая-то подстрока в тексте совпала с шаблоном, все подстроки, которые совпали с подшаблонами этого РВ, тоже возвращаются в качестве результата. Скобки, обозначающие начало подшаблона, пересчитываются слева направо (начиная с 1) для того, чтобы узнать, сколько подшаблонов нужно захватить.
Например, имеется такой шаблон:
победитель получит
((золотую|позолоченный)
(медаль|кубок))

и строка, в которой ищутся совпадения с этим шаблоном: «победитель получит золотую медаль». Тогда кроме этой фразы будут еще захвачены и выданы как результаты поиска следующие совпадения в подвыражениях: «золотую медаль», «золотую», «медаль», пронумерованные 1, 2, 3 соответственно.

Однако это не всегда удобно. Для того чтобы избавиться от «захватывающего» эффекта подвыражения, после открывающей скобки пишут «?:». Тогда это подвыражение в результат поиска не включается и при нумерации остальных подшаблонов с «захватывающим» эффектом не учитывается.
победитель получит
((?:золотую|позолоченный)
(медаль|кубок))

Тогда в условиях предыдущего примера получим искомую строку «победитель получит золотую медаль» и строки «золотую медаль», «медаль», пронумерованные 1 и 2 соответственно.

Если в html-файле название находится после и отделено от него только пробелами или переводами строк, заключено в тег

и
после него тоже может идти сколько-то пробелов и переводов строк, то его можно найти с помощью следующего скрипта:


Заметим, что здесь выводится первое захваченное подвыражение, поскольку нам интересно только само название, а не все РВ. Так как в этом РВ есть только одно подвыражение, то его значение содержится в нулевом элементе первого массива результатов.
Повторения (квантификаторы)

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

Квантификаторы могут следовать за любым из перечисленных элементов:

  • одиночный символ (возможно, в комбинации с обратным слэшем);
  • метасимвол «.»;
  • символьный класс;
  • обратная ссылка (о них расскажем позднее);
  • подшаблон.

Общие квантификаторы задают минимальное и максимальное число дозволенных повторений элемента;
эти два числа, разделенные запятой, заключаются в фигурные скобки. Числа не должны превышать
65 536 и первое число должно быть меньше или равно второму. Например, x говорит о том,
что символ «x» должен повторяться минимум один, а максимум три раза.
Соответственно этому шаблону удовлетворяют строки: x, xx, xxx.

Если второй параметр отсутствует, но запятая есть, то повторений может быть сколько угодно.
Таким образом, [aeuoi] значит, что любой из символов «a», «e», «u», «o», «i»
в строке может повторяться два и более раз, а регулярное выражение \d
задает ровно три цифры.

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

Исходя из исторических традиций три наиболее часто встречающихся квантификатора имеют следующие обозначения:

  • * эквивалентно <0,>– то есть это ноль и более повторений;
  • + эквивалентно <1,>– то есть это одно и более повторений;
  • ? эквивалентно <0,1>– то есть это ноль или одно повторение.

Есть еще один важный момент, на который стоит обратить внимание при изучении квантификаторов.
По умолчанию все квантификаторы «жадные», они стараются захватить как можно
больше повторений элемента. То есть если указать, что символ должен повторяться один и более раз
(например, с помощью *), совпадение произойдет со строкой, содержащей наибольшее число повторений
указанного символа. Это может создать проблемы, например, при попытке выделить комментарии в
программе на языке Cи или PHP. Комментарии в Cи и PHP записываются между символами /* и */,
внутри которых тоже могут встречаться символы * и /. И попытка выявить Си-комментарии с помощью шаблона
/\* .* \*/ в строке /* первый комментарий */ не комментарий /* второй комментарий */
не увенчается успехом из-за «жадности» элемента «.*» (будет найдена также строка «не комментарий»).
Для решения этой проблемы нужно написать знак вопроса после квантификатора. Тогда он перестанет быть
«жадным» и попытается захватить как можно меньшее число повторений элемента, к которому он применен
(квантификатор применяется к элементу, что стоит перед ним). Так что шаблон /\* .*? \*/
успешно выделяет Си-комментарии.

В PHP существует опция PCRE_UNGREEDY, которая делает все квантификаторы «не жадными» по умолчанию и «жадными», если после них идет знак вопроса.

HackWare.ru

Этичный хакинг и тестирование на проникновение, информационная безопасность

Регулярные выражения в PHP (ч. 2)

Оглавление

Первая часть:

Вторая часть:

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

Общие типы символов

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

Например, далее рассмотрены способы указания общего типа символов — некоторые из этих способов записи являются альтернативным синтаксисом к уже рассмотренным. Допустим если мы хотим указать в регулярном выражении «любая цифра», то мы можем использовать [0-9]. Также имеется ещё один вариант записи с помощью экранирующих последовательностей. «Любая десятичная цифра» в них обозначается как \d.

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

Среди экранирующих последовательностей есть элементы синтаксиса, который невозможно передать иным способом. Примеры будут показаны далее.

Общие типы символов обозначаются так:

\d

любая десятичная цифра

\D

любой символ, кроме десятичной цифры

\h

любой горизонтальный пробельный символ

\H

любой символ, не являющийся горизонтальным пробельным символом

\s

любой пробельный символ

\S

любой непробельный символ

\v

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

\V

любой символ, не являющийся вертикальным пробельным символом

\w

Любой символ, образующий «слово»

\W

Любой символ, не образующий «слово»

Каждая пара таких специальных последовательностей делит полное множество всех символов на два непересекающихся множества. Любой символ соответствует одному и только одному множеству из пары.

Следующие символы считаются как «пробельные»: HT (9), LF (10), FF (12), CR (13), и пробел (32). Тем не менее, если идет локале-зависимый поиск, и произойдет совпадение с символами в диапазоне 128-255, они также будут восприняты как пробельные, например NBSP (A0).

Символ, образующий «слово» — это произвольная цифра, буква или символ подчеркивания, проще говоря, любой символ, который может являться частью «слова» в Perl. Определение букв и цифр управляется символьными таблицами, с которыми была собрана PCRE. И, как следствие, эти наборы могут отличаться в различных локализированных дистрибутивах. Например, в локали «fr» (Франция) некоторые символы с кодом выше 128 используются для записи ударных символов и, соответственно, соответствуют маске \w.

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

У этих символов может быть весьма полезное применение. Давайте вспомним (чуть переделанное) регулярное выражение для вывода HTML тэга всех заголовков вместе с конечным тегом, а также вместе с самим содержанием заголовка:

Используя уже известный код:

я получил вот такой результат:

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

А если запись разбита на несколько строк, например так:

то такие заголовки найдены не были.

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

Проблема в нашем регулярном выражении, которое мы написали — мы не указали, что после открывающего тэга заголовка могут идти пробелы. Затем после содержимого заголовка также могут идти пробелы. Давайте составим новое регулярное выражение, с учётом этого. Любые пробельные символы обозначаются как \s. Их может не быть вовсе, а может быть несколько, поэтому в качестве квантора нужно использовать звёздочку, получаем \s*. Эту конструкцию вставляем два раза: 1) между открывающим HTML тэгом и содержимым заголовка; 2) между концом содержимого заголовка и закрывающим HTML тэгом.

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

В результате находим 51 заголовок — видимо, это все заголовки анализируемой страницы, среди них как написанный в одну строку, так и многострочные.

В подобных случаях также можно использовать модификатор регулярного выражения s. Подробности и примеры смотрие в статье «Поиск по нескольким строкам в PHP с функциями preg_match_all и preg_match».

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

Непечатные символы в видимой форме в описании шаблона

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

\a

символ оповещения, сигнал, (BEL, шестнадцатеричный код 07)

\cx

«Ctrl+x«, где x — произвольный символ

\e

escape (шестнадцатеричный код 1B)

\f

разрыв страницы (шестнадцатеричный код 0C)

\n

перевод строки (шестнадцатеричный код 0A)

символ со свойством xx, подробнее смотрите свойства unicode

символ без свойства xx, подробнее смотрите свойства unicode

\r

возврат каретки (шестнадцатеричный код 0D)

\R

разрыв строки: совпадает с \n, \r и \r\n

\t

табуляция (шестнадцатеричный код 09)

\xhh

символ с шестнадцатеричным кодом hh

\ddd

символ с восьмеричным кодом ddd, либо ссылка на подмаску

Если быть более точным, комбинация «\cx» интерпретируется следующим образом: если «x» — символ нижнего регистра, он преобразуется в верхний регистр. После этого шестой бит символа (шестнадцатеричный код 40) инвертируется. Таким образом «\cz» интерпретируется как шестнадцатеричное значение 1A, в то время как «\c<" получает шестнадцатеричное значение 3B, а "\c;" - 7B.

После «\x» считываются еще две шестнадцатеричные цифры (они могут быть записаны в нижнем или верхнем регистре). В режиме UTF-8, разрешается использование «\x<. >«, где содержимое скобок является строкой из шестнадцатеричных цифр. Она интерпретируется как символ UTF-8 character с кодом, совпадающим с данным шестнадцатеричным числом. Исходная шестнадцатеричная экранирующая последовательность, \xhh, совпадает с двухбайтным UTF-8 символом, если его значение превышает 127.

После «\0» считываются две восьмеричные цифры. Если в записи менее двух цифр, будут использованы все фактически присутствующие цифры. Таким образом, последовательность «\0\x\07» будет интерпретирована как два бинарных нуля, за которыми следует символ оповещения (звонок). В случае, если вы используете представление числа в восьмеричном коде, убедитесь, что за начальным нулем следуют две значащие цифры.


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

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

\040

еще один способ записи пробела

\40

то же самое в случае, если данной записи предшествует менее сорока подмасок

\7

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

\11

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

\011

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

\0113

символ табуляции, за которым следует цифра «3»

\113

интерпретируется как символ с восьмеричным кодом 113 (так как ссылок на подмаски не может быть более чем 99)

\377

байт, всецело состоящий из единичных битов

\81

либо обратная ссылка, либо бинарный ноль, за которым следуют цифры «8» и «1»

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

Все последовательности, определяющие однобайтное значение, могут встречаться как внутри, так и вне символьных классов. Кроме того, внутри символьного класса запись «\b» интерпретируется как символ возврата (‘backspace’, шестнадцатеричный код 08). Вне символьного класса она имеет другое значение (какое именно, описано ниже).

Определение формальных утверждений

Ещё одно использование обратного слеша — определение некоторых формальных утверждений, описывающих условия касательно месторасположения особых позиций в строке и совершенно не затрагивающих сами символы. Использование подмасок как более сложных формальных утверждений описано далее. Такими управляющими последовательностями являются:

\b

\B

не является границей слова

\A

начало данных (независимо от многострочного режима)

\Z

конец данных либо позиция перед последним переводом строки (независимо от многострочного режима)

\z

конец данных (независимо от многострочного режима)

\G

первая совпадающая позиция в строке

Описанные выше последовательности не могут встречаться в символьных классах (исключая комбинацию «\b«, которая внутри класса означает символ возврата ‘backspace’).

Границей слова считается такая позиция в строке, в которой из текущего и предыдущего символа только один соответствует \w или \W (т.е. один из них соответствует \w, а другой \W). Начало или конец строки также соответствуют границе слова в случае, если первый или, соответственно, последний символ совпадает с \w.

Специальные последовательности \A, \Z и \z отличаются от общеупотребляемых метасимволов начала строки ‘^‘ и конца строки ‘$‘ (описанных в разделе якоря первой части) тем, что они всегда совпадают либо в самом начале либо в самом конце строки. На них никак не влияют опции m (PCRE_MULTILINE) и D (PCRE_DOLLAR_ENDONLY). Разница между \Z и \z в том, что \Z соответствует позиции перед последним символом в случае, если последний символ — перевод строки, кроме самого конца строки. В то время, как \z соответствует исключительно концу данных.

Утверждение \G является истинным только в том случае, если текущая проверяемая позиция находится в начале совпадения, указанного параметром offset функции preg_match(). Она отличается от \A при ненулевом значении параметра offset.

\Q и \E могут быть использованы для игнорирования метасимволов регулярных выражений в шаблоне. Например: \w+\Q.$.\E$ совпадет с один или более символов, составляющих «слово»,за которыми следуют символы .$. и якорь в конце строки.

Последовательность \K может быть использована для сброса начала совпадения. Например, шаблон foo\Kbar совпадет с «foobar», но сообщит о том, что совпал только с «bar». Использование \K не мешает установке подмасок. Например, если шаблон (foo)\Kbar совпадет со строкой «foobar», первой подмаской все равно будет являться «foo».

POSIX нотация для символьных классов

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

alnum буквы и цифры
alpha буквы
ascii символы с кодами 0 — 127
blank только пробел или символ табуляции
cntrl управляющие символы
digit десятичные цифры (то же самое, что и \d)
graph печатные символы, исключая пробел
lower строчные буквы
print печатные символы, включая пробел
punct печатные символы, исключая буквы и цифры
space пробельные символы(почти то же самое, что и \s)
upper прописные буквы
word символы «слова» (то же самое, что и \w)
xdigit шестнадцатеричные цифры

Класс пробельных символов (space) — это горизонтальная табуляция (HT, 9), перевод строки (LF, 10), вертикальная табуляция (VT, 11), разрыв страницы (FF, 12), возврат каретки (CR, 13) и пробел (32). Учтите, что этот список включает вертикальную табуляцию (VT, код 11). Это отличает «space» от \s, который не включает этот символ (для совместимости с Perl).

Название word — это расширение Perl, а blank — расширение GNU, начиная с версии Perl 5.8. Другое расширение Perl — это отрицание, которое указывается символом ^ после двоеточия. Например, [12[:^digit:]] совпадет с «1», «2», или с любой не-цифрой.

В режиме UTF-8, символы со значениями, превышающими 128, не совпадут ни с одним из символьных классов POSIX. Начиная с PHP 5.3.0 и libpcre 8.10 некоторые символьные классы изменены, чтобы использовать свойства символов Unicode, в этом случае упомянутое ограничение не применяется. Читайте руководство PCRE(3) для подробностей.

Подмаски

Подмаска — это часть регулярного выражения, которая участвует в поиске. Подмаска может выполнять несколько функций:

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

2) найденная в подмаске строка может вновь использоваться в регулярном выражении в качестве обратной ссылке (о них позже)

Подмаски в регулярном выражении выделяются скобками. В регулярном выражении может быть более чем одна подмаска, в этом случае они нумеруются слева направо.

Подмаски могут быть вложенными одна в другую.

При использовании функции preg_match_all возвращается массива, где в качестве первого элемента (с индексом 0) возвращается массив с найденными значениями строк. Если указаны подмаски, то в качестве второго элемента возвращаемого массива (с индексом 1) будет массив с найденными строками, соответствующими первой подмаске. Если используется две подмаски, то будет возвращён ещё один массив и так далее для каждой последующей подмаске.

Как мы помним из первой части, описывающий синтаксис регулярных выражений, скобки имеют и другое значение: или использовании оператора | (ИЛИ) они ограничивают варианты альтернатив друг от друга. Например, шаблон cat(aract|erpillar|) соответствует одному из слов «cat», «cataract» или «caterpillar». Без использования скобок он соответствовал бы строкам «cataract», «erpillar» или пустой строке.

То есть скобки выполняют одновременно две функции.

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

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

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

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

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

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

В этом шаблоне обе подмаски Sun и Sat будут сохранены под номером 1.

Обратные ссылки в PHP

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

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

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

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

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

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

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

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

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

К примеру, я хочу найти строки, состоящие из пяти любых, но одинаковых цифр, например, «11111», «22222» и так далее, в этом случае я могу написать следующее регулярное выражение:

Как мы рассмотрели чуть выше, экранирующая последовательность \d обозначает любую цифру. Для того, чтобы найденную строку можно было использовать в качестве обратной ссылке, мы заключаем эту часть регулярного выражения в круглые скобки. То есть получается, что мы создаём подмаску в регулярном выражении. Затем идёт обратный слэш \ с цифрой 1 — это и есть обратная ссылка. То есть, что бы ни было найдено в первой подмаске, его значение будет помещено в обратную ссылку \1. Затем ещё идут три таких же обратных ссылки. Получается что регулярное выражение ищет любую цифру, за которой ещё четыре раза идёт эта же самая цифра.

Для поиска возьмём строку:

даст следующий результат:

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

Рассмотрим более практический пример. Допустим мы хотим найти в HTML коде все пары тэгов: открывающий и закрывающий тэг, между которыми идёт какой-либо текст. Есть исключения (например,
, и так далее) — но не будем их рассматривать, чтобы не усложнять пример.

Тэг абзаца выглядит примерно так:

Тэг раздела страницы:

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

Любая буква в угловых скобках обозначается так:

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

Закрывающим тэгом будет обратная ссылка, содержащая найденное название тэга, помещённая между , то есть:

Поскольку в качестве разделителя используется слэш, то тот слэш, который означает «буквальный слэш» нужно экранировать, чтобы он потерял своё специальное значение и стал трактоваться как буквальный символ, получаем:

Составленное регулярное выражение будет соответствовать тэгам в следующем написании:

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

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

Функции PHP для поиска и замены по регулярному выражению


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

  • preg_filter — Производит поиск и замену по регулярному выражению
  • preg_replace_callback_array — Выполняет поиск и замену по регулярному выражению с использованием функций обратного вызова
  • preg_replace_callback — Выполняет поиск по регулярному выражению и замену с использованием callback-функции
  • preg_replace — Выполняет поиск и замену по регулярному выражению

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

Функция preg_replace_callback позволяет делать интеллектуальную замену. Её суть заключается в том, что не просто выполняется замена найденной строки, а вызывается функция, которой передаётся совпавшая строка, и эта функция уже и возвращает строку с заменой. Вместо элементарной замены, функция может, например, делать дополнительную проверку полученных данных и уже на основе принятого решения выполнять ту или иную замену. Можно установить счётчик и делать замену в каждом n-ной совпавшей строке — например, в каждой третьей или каждой десятой. Можно пронумеровать найденные строки и делать любые другие изменения, которые не ограничиваются обычным поиском и заменой на фиксированную строку.

Пример использование функции preg_replace_callback:

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

Пример моего реального недавнего использования функции preg_replace_callback на практике — добавления рекламы в каждый десятый комментарий — с её помощью очень легко реализовать подобную логику.

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

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

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

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

Если вам не нужна мощь регулярных выражений, то вместо preg_split вы можете выбрать более быстрые (хоть и простые) альтернативы наподобие explode() или str_split().

preg_match

(PHP 4, PHP 5, PHP 7)

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

Описание

Ищет в заданном тексте subject совпадения с шаблоном pattern .

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

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

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

flags может быть комбинацией следующих флагов: PREG_OFFSET_CAPTURE

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

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

PREG_UNMATCHED_AS_NULL

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

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

Обычно поиск осуществляется слева направо, с начала строки. Можно использовать дополнительный параметр offset для указания альтернативной начальной позиции для поиска (в байтах).

Использование параметра offset не эквивалентно замене сопоставляемой строки выражением substr($subject, $offset) при вызове функции preg_match() , поскольку шаблон pattern может содержать такие условия как ^, $ или (? = «abcdef» ;
$pattern = ‘/^def/’ ;
preg_match ( $pattern , $subject , $matches , PREG_OFFSET_CAPTURE , 3 );
print_r ( $matches );
?>

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

В то время как этот пример

В качестве альтернативы substr()() , используйте утверждение \G вместо якоря ^ или модификатор A. Оба они работают с параметром offset .

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

preg_match() возвращает 1, если параметр pattern соответствует переданному параметру subject , 0 если нет, или FALSE в случае ошибки.

Эта функция может возвращать как логическое значение FALSE , так и значение не типа boolean, которое приводится к FALSE . За более подробной информацией обратитесь к разделу Булев тип. Используйте оператор === для проверки значения, возвращаемого этой функцией.

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

Версия Описание
7.2.0 Теперь константа PREG_UNMATCHED_AS_NULL поддерживается для параметра $flags .
5.3.6 Возвращает FALSE , если offset больше, чем длина subject .
5.2.2 Именованные подмаски теперь позволяют синтаксис (? ) и (?’name’), также как и (?P ). Предыдущие версии позволяли только (?P ).

Примеры

Пример #1 Поиск подстроки «php» в тексте

Пример #2 Поиск слова «web» в тексте

/* Специальная последовательность \b в шаблоне означает границу слова,
следовательно, только изолированное вхождение слова ‘web’ будет
соответствовать маске, в отличие от «webbing» или «cobweb» */
if ( preg_match ( «/\bweb\b/i» , «PHP is the web scripting language of choice.» )) <
echo «Вхождение найдено.» ;
> else <
echo «Вхождение не найдено.» ;
>

if ( preg_match ( «/\bweb\b/i» , «PHP is the website scripting language of choice.» )) <
echo «Вхождение найдено.» ;
> else <
echo «Вхождение не найдено.» ;
>
?>

Пример #3 Извлечение доменного имени из URL

// Извлекаем имя хоста из URL
preg_match ( ‘@^(?:http://)?([^/]+)@i’ ,
«http://www.php.net/index.html» , $matches );
$host = $matches [ 1 ];

// извлекаем две последние части имени хоста
preg_match ( ‘/[^.]+\.[^.]+$/’ , $host , $matches );
echo «доменное имя: < $matches [ 0 ]>\n» ;
?>

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

Пример #4 Использование именованных подмасок

preg_match ( ‘/(?P \w+): (?P \d+)/’ , $str , $matches );

/* Это также работает в PHP 5.2.2 (PCRE 7.0) и более поздних версиях,
однако вышеуказанная форма рекомендуется для обратной совместимости */
// preg_match(‘/(? \w+): (? \d+)/’, $str, $matches);

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

Примечания

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

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

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

User Contributed Notes 46 notes

Regex quick reference
[abc] A single character: a, b or c
[^abc] Any single character but a, b, or c
[a-z] Any single character in the range a-z
[a-zA-Z] Any single character in the range a-z or A-Z
^ Start of line
$ End of line
\A Start of string
\z End of string
. Any single character
\s Any whitespace character
\S Any non-whitespace character
\d Any digit
\D Any non-digit
\w Any word character (letter, number, underscore)
\W Any non-word character
\b Any word boundary character
(. ) Capture everything enclosed
(a|b) a or b
a? Zero or one of a
a* Zero or more of a
a+ One or more of a
a <3>Exactly 3 of a
a <3,>3 or more of a
a <3,6>Between 3 and 6 of a

options: i case insensitive m make dot match newlines x ignore whitespace in regex o perform # <. >substitutions only once

Sometimes its useful to negate a string. The first method which comes to mind to do this is: [^(string)] but this of course won’t work. There is a solution, but it is not very well known. This is the simple piece of code on how a negation of a string is done:

?: makes a subpattern (see http://www.php.net/manual/en/regexp.reference.subpatterns.php) and ?! is a negative look ahead. You put the negative look ahead in front of the dot because you want the regex engine to first check if there is an occurrence of the string you are negating. Only if it is not there, you want to match an arbitrary character.

Hope this helps some ppl.

I noticed that in order to deal with UTF-8 texts, without having to recompile php with the PCRE UTF-8 flag enabled, you can just add the following sequence at the start of your pattern: (*UTF8)

for instance : ‘#(*UTF8)[[:alnum:]]#’ will return TRUE for ‘é’ where ‘#[[:alnum:]]#’ will return FALSE

found this very very useful tip after hours of research over the web directly in pcre website right here : http://www.pcre.org/pcre.txt
there are many further informations about UTF-8 support in the lib

hop that will help!

Was working on a site that needed japanese and alphabetic letters and needed to
validate input using preg_match, I tried using \p