Php руководство по рнр 3 0 функции регулярных выражений


Содержание

Популярные примеры работы регулярных выражений в 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 адреса в тексте

ГЛАВА 8 Строки и регулярные выражения в PHP

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

Поиск по шаблону позволяет не только находить определенные фрагменты текста, но и заменять их другими фрагментами. Одним из стандартных примеров поиска по шаблону являются команды поиска/замены в текстовых редакторах — например, в MS Word, Emacs и в моем любимом редакторе vi. Всем пользователям UNIX хорошо известны такие программы, как sed, awk и grep; богатство возможностей этих программ в значительной степени обусловлено средствами поиска по шаблону. Механизмы поиска по шаблону решают четыре основные задачи:

  • поиск строк, в точности совпадающих с заданным шаблоном;
  • поиск фрагментов строк, совпадающих с заданным шаблоном;
  • замену строк и подстрок по шаблону;
  • поиск строк, с которыми заданный шаблон не совпадает.

Появление Web породило необходимость в более быстрых и эффективных средствах поиска данных, которые бы позволяли пользователям со всего мира находить нужную информацию среди миллиардов web-страниц. Поисковые системы, онлайновые финансовые службы и сайты электронной коммерции — все это стало бы абсолютно бесполезным без средств анализа гигантских объемов данных в этих секторах. Действительно, средства обработки строковой информации являются жизненно важной составляющей практически любого сектора, так или иначе связанного с современными информационными технологиями. В этой главе основное внимание посвящено средствам обработки строк в PHP. Мы рассмотрим некоторые стандартные строковые функции (в языке их больше 60!), а из приведенных определений и примеров вы получите сведения, необходимые для создания web-приложений. Но прежде чем переходить к специфике PHP, я хочу познакомить вас с базовым механизмом, благодаря которому становится возможным поиск по шаблону. Речь идет о регулярных выражениях.

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

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

В PHP существуют два семейства функций, каждое из которых относится к определенному типу регулярных выражений: в стиле POSIX или в стиле Perl. Каждый тип регулярных выражений обладает собственным синтаксисом и рассматривается в соответствующей части главы. На эту тему были написаны многочисленные учебники, которые можно найти как в Web, так и в книжных магазинах. Поэтому я приведу лишь основные сведения о каждом типе, а дальнейшую информацию при желании вы сможете найти самостоятельно. Если вы еще не знакомы с принципами работы регулярных выражений, обязательно прочитайте краткий вводный курс, занимающий всю оставшуюся часть этого раздела. А если вы хорошо разбираетесь в этой области, смело переходите к следующему разделу.

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

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

Простейшее регулярное выражение совпадает с одним литеральным символом — например, выражение g совпадает в таких строках, как g , haggle и bag. Выражение, полученное при объединении нескольких литеральных символов, совпадает по тем же правилам — например, последовательность gan совпадает в любой строке, содержащей эти символы (например, gang, organize или Reagan).

Оператор | (вертикальная черта) проверяет совпадение одной из нескольких альтернатив. Например, регулярное выражение php | zend проверяет строку на наличие php или zend.

Квадратные скобки ([ ]) имеют особый смысл в контексте регулярных выражений — они означают «любой символ из перечисленных в скобках». В отличие от регулярного выражения php, которое совпадает во всех строках, содержащих литеральный текст php, выражение [php] совпадает в любой строке, содержащей символы р или h. Квадратные скобки играют важную роль при работе с регулярными выражениями, поскольку в процессе поиска часто возникает задача поиска символов из заданного интервала. Ниже перечислены некоторые часто используемые интервалы:

  • [0-9] — совпадает с любой десятичной цифрой от 0 до 9;
  • [a-z] — совпадает с любым символом нижнего регистра от а до z;
  • [A-Z] — совпадает с любым символом верхнего регистра от А до Z;
  • [a -Z] — совпадает с любым символом нижнего или верхнего регистра от а до Z.

Конечно, перечисленные выше интервалы всего лишь демонстрируют общий принцип. Например, вы можете воспользоваться интервалом [0-3] для обозначения любой десятичной цифры от 0 до 3 или интервалом [b-v] для обозначения любого символа нижнего регистра от b до v. Короче говоря, интервалы определяются совершенно произвольно.

Существует особый класс служебных символов, обозначающих количество повторений отдельного символа или конструкции, заключенной в квадратные скобки. Эти служебные символы (+, * и <. >) называются квантификаторами. Принцип их действия проще всего пояснить на примерах:

  • р+ означает один или несколько символов р, стоящих подряд;
  • р* означает ноль и более символов р, стоящих подряд;
  • р? означает ноль или один символ р;
  • р <2>означает два символа р, стоящих подряд;
  • р <2,3>означает от двух до трех символов р, стоящих подряд;
  • р <2,>означает два и более символов р, стоящих подряд.

Прочие служебные символы

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

  • Конструкция [^a-zA-Z] совпадает с любым символом, не входящим в указаные интервалы (a-z и A-Z).
  • Служебный символ . (точка) означает «любой символ». Например, выражение р.р совпадает с символом р, за которым следует произвольный символ, после чего опять следует символ р.

Объединение служебных символов приводит к появлению более сложных выражений. Рассмотрим несколько примеров:

  • ^.<2>$ — любая строка, содержащая ровно два символа;
  • (.*) — произвольная последовательность символов, заключенная между и (вероятно, тегами HTML для вывода жирного текста);
  • p(hp)* — символ р, за которым следует ноль и более экземпляров последовательности hp (например, phphphp).

Иногда требуется найти служебные символы в строках вместо того, чтобы использовать их в описанном специальном контексте. Для этого служебные символы экранируются обратной косой чертой (\). Например, для поиска денежной суммы в долларах можно воспользоваться выражением \$[0-9]+, то есть «знак доллара, за которым следует одна или несколько десятичных цифр». Обратите внимание на обратную косую черту перед $. Возможными совпадениями для этого регулярного выражения являются $42, $560 и $3.

Стандартные интервальные выражения (символьные классы)

Для удобства программирования в стандарте POSIX были определены некоторые стандартные интервальные выражения, также называемые символьными классами (character classes). Символьный класс определяет один символ из заданного интервала — например, букву алфавита или цифру:

  • [[:alpha:]] — алфавитный символ (aA-zZ);
  • [[:digit:]]-цифра (0-9);
  • [[:alnum:]] — алфавитный символ (aA-zZ) или цифра (0-9);
  • [[:space:]] — пропуски (символы новой строки, табуляции и т. д.).

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

В настоящее время PHP поддерживает семь функций поиска с использованием регулярных выражений в стиле POSIX:

Описания этих функций приведены в следующих разделах.

Функция еrеg( ) ищет в заданной строке совпадение для шаблона. Если совпадение найдено, возвращается TRUE, в противном случае возвращается FALSE. Синтаксис функции ereg( ):

int ereg (string шаблон, string строка [, array совпадения])

Поиск производится с учетом регистра алфавитных символов. Пример использования ereg( ) для поиска в строках доменов .соm:

$is_com — ereg(«(\.)(com$)», $email):

// Функция возвращает TRUE, если $email завершается символами «.com»

// В частности, поиск будет успешным для строк

// «www.wjgilmore.com» и «someemail@apress.com»

Обратите внимание: из-за присутствия служебного символа $ регулярное выражение совпадает только в том случае, если строка завершается символами .com. Например, оно совпадет в строке «www.apress.com», но не совпадет в строке «www.apress.com/catalog».

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

Листинг 8.1. Вывод элементов массива $regs

// Разделить $url на три компонента: «http://www». «apress» и «com»

if ($www_url) : // Если переменная $www_url содержит URL

echo $regs[0]; // Вся строка «http://www.apress.com»

echo $regs[l]; // «http://www»

echo $regs[2]; // «apress»

echo $regs[3]; // «com» endif;

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

http://www.apress.com http://www apress com

Функция ereg_replace( ) ищет в заданной строке совпадение для шаблона и заменяет его новым фрагментом. Синтаксис функции ereg_replace( ):

string ereg_replace (string шаблон, string замена, string строке)

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

отсутствуют, строка остается в прежнем состоянии. Функция ereg_replace( ), как и еrеg( ), учитывает регистр символов. Ниже приведен простой пример, демонстрирующий применение этой функции:

$copy_date = «Copyright 1999»:

$copy_date = ereg_replace(«([0-9]+)». «2000», $copy_date);

print $copy_date: // Выводится строка «Copyright 2000»

У средств поиска с заменой в языке PHP имеется одна интересная возможность — возможность использования обратных ссылок на части основного выражения, заключенные в круглые скобки. Обратные ссылки похожи на элементы необязательного параметра-массива совпадения функции еrеg( ) за одним исключением: обратные ссылки записываются в виде \0, \1, \2 и т. д., где \0 соответствует всей строке, \1 — успешному совпадению первого подвыражения и т. д. Выражение может содержать до 9 обратных ссылок. В следующем примере все ссылки на URL в тексте заменяются работающими гиперссылками:

$url = «Apress (http://www.apress.com»);

Функция eregi( ) ищет в заданной строке совпадение для шаблона. Синтаксис функции eregi( ):

int eregi (string шаблон, string строка [, array совпадения])

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

print «Invalid password! Passwords must be from 8 through 10 characters in length.»;

// В результате выполнения этого фрагмента выводится сообщение об ошибке.

// поскольку длина строки «abc» не входит в разрешенный интервал

// от 8 до 10 символов.

Функция eregi_replасе( ) работает точно так же, как ereg_replace( ), за одним исключением: поиск производится без учета регистра символов. Синтаксис функции ereg_replace( ):

string eregi_replace (string шаблон, string замена, string строка)

Функция split( ) разбивает строку на элементы, границы которых определяются по заданному шаблону. Синтаксис функции split( ):

array split (string шаблон, string строка [, int порог])

Необязательный параметр порог определяет максимальное количество элементов, на которые делится строка слева направо. Если шаблон содержит алфавитные символы, функция spl it( ) работает с учетом регистра символов. Следующий пример демонстрирует использование функции split( ) для разбиения канонического IP-адреса на триплеты:

$ip = «123.345.789.000»; // Канонический IP-адрес

$iparr = split («\.», $ip) // Поскольку точка является служебным символом.

// ее необходимо экранировать.

print «$iparr[0]
«; // Выводит «123»

print «$iparr[1]
«; // Выводит «456»

print «$iparr[2]
«; // Выводит «789»

print «$iparr[3]
«; // Выводит «000»

Функция spliti( ) работает точно так же, как ее прототип split( ), за одним исключением: она не учитывает регистра символов. Синтаксис функции spliti( ):

array spliti (string шаблон, string строка [, int порог])

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

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

string sql_regcase (string строка)

Если алфавитный символ существует в двух вариантах (верхний и нижний регистры), выражение в квадратных скобках будет содержать оба варианта; в противном случае исходный символ повторяется дважды. Функция sql_regcase( ) особенно удобна при использовании PHP с программными пакетами, поддерживающими регулярные выражения в одном регистре. Пример преобразования строки функцией sql_regcase( ):

$version = «php 4.0»;

// Выводится строка [Pp][Hh][Pp][ ][44][..][00]

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

Perl ( http://www.perl.com ) давно считается одним из самых лучших языков обработки текстов. Синтаксис Perl позволяет осуществлять поиск и замену даже для самых сложных шаблонов. Разработчики РHР сочли, что не стоит заново изобретать уже изобретенное, а лучше сделать знаменитый синтаксис регулярных выражений Perl доступным для пользователей PHP. Так появились функции для работы с регулярными выражениями в стиле Perl.

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

Оставшаяся часть этого раздела будет посвящена краткому знакомству с диалектом регулярных выражений Perl. Рассмотрим простой пример:

Обратите внимание: строка food заключена между двумя косыми чертами. Как и в стандарте POSIX, вы можете создавать более сложные шаблоны при помощи квантификаторов:

Этот шаблон совпадает с последовательностью fo, за которой могут следовать дополнительные символы о. Например, совпадения будут обнаружены в строках food, fool и fo4. Рассмотрим другой пример использования квантификатора:

Шаблон совпадает с символом f, за которым следуют от 2 до 4 экземпляров символа о. К числу потенциальных совпадений относятся строки fool , fooool и foosball .

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

Метасимволы

Одной из интересных особенностей Perl является использование метасимволов при поиске. Метасимвол [Следует отметить, что авторское толкование термина «метасимвол» противоречит не только всем традициям, по и официальной документации PHP. — Примеч. перев. ] представляет собой алфавитный символ с префиксом \ — признаком особой интерпретации следующего символа. Например, метасимвол \d может использоваться при поиске денежных сумм:

Комбинация \d обозначает любую цифру. Конечно, в процессе поиска часто возникает задача идентификации алфавитно-цифровых символов, поэтому в Perl для них был определен метасимвол \w:

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

Еще один полезный метасимвол, \b, совпадает с границами слов:

Поскольку метасимвол границы слова расположен справа от текста, этот шаблон совпадет в строках salsa и lisa, но не в строке sand. Противоположный метасимвол, \В, совпадает с чем угодно, кроме границы слова:

Шаблон совпадает в таких строках, как sand и Sally, но не совпадает в строке salsa.

Модификаторы

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

Таблица 8.1. Примеры модификаторов

m Фрагмент текста интерпретируется как состоящий из нескольких «логических строк». По умолчанию специальные символы ^ и $ совпадают только в начале и в конце всего фрагмента. При включении «многострочного режима» при помощи модификатора m^ и $ будут совпадать в начале и в конце каждой логической строки внутри фрагмента s По смыслу противоположен модификатору m — при поиске фрагмент интерпретируется как одна строка, а все внутренние символы новой строки игнорируются i Поиск выполняется без учета регистра символов

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

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

В PHP существует пять функций поиска по шаблону с использованием Perl-совместимых регулярных выражений:

  • preg_match( );
  • preg_match_all( );
  • preg_replace( );
  • preg_split( );
  • preg_grep( ).

Эти функции подробно описаны в следующих разделах.

Функция pregjnatch( ) ищет в заданной строке совпадение для шаблона. Если совпадение найдено, возвращается TRUE, в противном случае возвращается FALSE. Синтаксис функции pregjnatch( ):

int pregjnatch (string шаблон, string строка [, array совпадения>)

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

$linе = «Vi is the greatest word processor ever created!»;

// Выполнить поиск слова «Vi» без учета регистра символов:

if (preg_match(«/\bVi\b\i», $line, $matcn)) :

print «Match found!»;

// Команда if в этом примере возвращает TRUE

Функция preg_match_all( ) находит все совпадения шаблона в заданной строке.

Синтаксис функции preg_match_all( ):

Int preg_match_all (string шаблон, string строка, array совпадения [, int порядок])

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

  • PREG_PATTERN_ORDER — используется по умолчанию, если параметр порядок не указан. Порядок, определяемый значением PREG_PATTERN_ORDER, на первый взгляд выглядит не совсем логично: первый элемент (с индексом 0) содержит массив совпадений для всего регулярного выражения, второй элемент (с индексом 1) содержит массив всех совпадений для первого подвыражения в круглых скобках и т. д.;
  • PREG_SET_ORDER — порядок сортировки массива несколько отличается от принятого по умолчанию. Первый элемент (с индексом 0) содержит массив с текстом, совпавшим со всеми подвыражениями в круглых скобках для первого найденного совпадения. Второй элемент (с индексом 1) содержит аналогичный массив для второго найденного совпадения и т. д.

Следующий пример показывает, как при помощи функции preg_match_al( ) найти весь текст, заключенный между тегами HTML . :

$user_info = «Name: Rasmus Lerdorf
Title: PHP Guru«;

preg_match_all («/(.*) /U», Suserinfo. $pat_array);

print $pat_array[0][0].»
«.pat_array[0][l].»\n»:

Функция preg_repl ace( ) работает точно так же, как и ereg_replасе( ), за одним исключением — регулярные выражения могут использоваться в обоих параметрах, шаблон и замена. Синтаксис функции preg_replace( ):

mixed preg_replace (mixed шаблон, mixed замена, mixed строка [, int порог])

Необязательный параметр порог определяет максимальное количество замен в строке. Интересный факт: параметры шаблон и замена могут представлять собой масивы. Функция preg_replace( ) перебирает элементы обоих массивов и выполняет замену по мере их нахождения.

Функция preg_spl it( ) аналогична split( ) за одним исключением — параметр шаблон может содержать регулярное выражение. Синтаксис функции preg_split( ):

array preg_split (string шаблон, string строка [, int порог [, int флаги]])

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

$fields = preg_split(«/\+<1.>/», $user_info);

while ($x 0, если строка2 меньше, чем строка1.

В следующем фрагменте сравниваются две одинаковые строки:

if ((strcmp($string1. $string2)) == 0) :

print «Strings are equivalent!»; endif;

// Команда if возвращает TRUE

Функция strcasecmp( ) работает точно так же, как strcmp( ), за одним исключением — регистр символов при сравнении не учитывается. Синтаксис функции strcasecmp( ):

int strcasecmp (string cтpoкa1, string строка2)

В следующем фрагменте сравниваются две одинаковые строки:

if ((strcmp($string1, $string2)) == 0) :

print «Strings are equivalent!»;

// Команда if возвращает TRUE

Функция strspn( ) возвращает длину первого сегмента строки1, содержащего символы, присутствующие в строке2. Синтаксис функции strspn( ):

int strspn (string строка1, string строка2)

Следующий фрагмент показывает, как функция strspn( ) используется для проверки пароля:

if (strspn($password, «1234567890») != strlen($password)) :

print «Password cannot consist solely of numbers!»;

Функция strcspn( ) возвращает длину первого сегмента строки1, содержащего символы, отсутствующие в строке2. Синтаксис функции strcspn( ):

int strcspn (string строка1, string строка2)

В следующем фрагменте функция strcspn( ) используется для проверки пароля:

if (strcspn($password, «1234567890») == 0) :

print «Password cannot consist solely of numbers!»;

Обработка строковых данных без применения регулярных выражений

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

Функция strtok( ) разбивает строку на лексемы по разделителям, заданным вторым параметром. Синтаксис функции strtok( ):

string strtok (string строка, string разделители)

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

$info = «WJ Gi1more:wjgilmore@hotmail.com | Columbus, Ohio»;

// Ограничители — двоеточие (:), вертикальная черта (|) и запятая (.) $tokens = «:|,»;

$tokenized = strtok($info, $tokens);

// Вывести элементы массива $tokenized

echo «Element = $tokenized
«;

// Обратите внимание: при последующих вызовах strtok

// первый аргумент не передается

Функция parse_str( ) выделяет в строке пары «переменная-значение» и присваивает значения переменных в текущей области видимости. Синтаксис функции parse_str( ):

void parse_str (string строка)

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

// После выполнения parse_str( ) доступны следующие переменные:

Поскольку эта функция создавалась для работы с URL, она игнорирует символ амперсанд (&).

Работа с формами HTML в PHP описана в главе 10.

Функция explode( ) делит строку на элементы и возвращает эти элементы в виде массива. Синтаксис функции explode( ):

array explode (string разделитель, string строка [, int порог])

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

$info = «wilson | baseball | indians»;

$user = explode(«|», $info);

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

Если функция explode( ) разделяет строку на элементы массива, то ее двойник — функция implode( ) — объединяет массив в строку. Синтаксис функции implode( ):

string implode (string разделитель, array фрагменты)

Формирование строки из массива продемонстрировано в следующем примере:

$ohio_cities = array («Columbus», «Youngstown», «Cleveland», «Cincinnati»);

$city_string = implode(«l», $ohio_cities);

// $city_string = «Columbus | Youngstown | Cleveland | Cincinnati»;

У implode( ) имеется псевдоним — функция join( ).

Функция strpos( ) находит в строке первый экземпляр заданной подстроки. Синтаксис функции strpos( ):

int strpos (string строка, string подстрока [, int смещение])

Необязательный параметр offset задает позицию, с которой должен начинаться поиск. Если подстрока не найдена, strpos( ) возвращает FALSE (0).

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

// В какой позиции в журнале впервые встречается 1999 год?

$pos = strpos($log, «1999»);

// $pos = 95. поскольку первый экземпляр «1999»

// находится в позиции 95 строки, содержащейся в переменной $log

Функция strrpos( ) находит в строке последний экземпляр заданного символа. Синтаксис функции strrpos( ):

int strpos (string строка, char символ)

По возможностям эта функция уступает своему двойнику — функции strpos( ), поскольку она позволяет искать только отдельный символ, а не всю строку. Если во втором параметре strrpos( ) передается строка, при поиске будет использован только ее первый символ.

Функция str_replace( ) ищет в строке все вхождения заданной подстроки и заменяет их новой подстрокой. Синтаксис функции str_replace( ):

string str_replace (string подстрока, string замена, string строка)

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

Если подстрока ни разу не встречается в строке, исходная строка не изменяется:

$favorite_food = «My favorite foods are ice cream and chicken wings»;

$favorite_food = str_replace(«chicken_wings», «pizza», $favohte_food);

// $favorite_food = «My favorite foods are ice cream and pizza»

Функция strstr( ) возвращает часть строки, начинающуюся с первого вхождения заданной подстроки. Синтаксис функции strstr( ):

string strstr (string строка, string подстрока)

В следующем примере функция strstr( ) используется для выделения имени домена из URL:

$url = «http://www.apress.com»; $domain — strstr($url, «.»);

Функция substr( ) возвращает часть строки, начинающуюся с заданной начальной позиции и имеющую заданную длину. Синтаксис функции substr( ):

string substr (string строка, int начало [, int длина])

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

  • если параметр начало положителен, возвращаемая подстрока начинается с позиции строки с заданным номером;
  • если параметр начало отрицателен, возвращаемая подстрока начинается с позиции (длина строки — начало);
  • если параметр длина положителен, в возвращаемую подстроку включаются все символы от позиции начало до позиции начало+длина. Если последняявеличина превышает длину строки, возвращаются символы до конца строки;
  • если параметр длина отрицателен, возвращаемая подстрока заканчивается на заданном расстоянии от конца строки.

Помните о том, что параметр начало определяет смещение от первого символа строки; таким образом, возвращаемая строка в действительности начинается с символа с номером (начало + 1).

Следующий пример демонстрирует выделение части строки функцией substr( ):

$car = «1944 Ford»; Smodel = substr($car, 6);

Пример с положительным параметром длина:

$model = substr($car, 0, 4);

Пример с отрицательным параметром длина:

$model = substr($car, 2, -5);

Функция substr_count( ) возвращает количество вхождений подстроки в заданную строку. Синтаксис функции substr_count( ):

int substr_count (string строка, string подстрока)

В следующем примере функция substr_count( ) подсчитывает количество вхождений подстроки ain:

$tng_twist = «The rain falls mainly on the plains of Spain»;

$count = substr_count($tng_twist, «ain»);

Функция substr_replace( ) заменяет часть строки, которая начинается с заданной позиции. Если задан необязательный параметр длина, заменяется фрагмент заданной длины; в противном случае производится замена по всей длине заменяющей строки. Синтаксис функции substr_replace( ):

string substr_replace (string строка, string замена, int начало [, int длина])

Параметры начало и длина задаются по определенным правилам:

  • если параметр начало положителен, замена начинается с заданной позиции;
  • если параметр начало отрицателен, замена начинается с позиции (длина строки -начало);
  • если параметр длина положителен, заменяется фрагмент заданной длины;
  • если параметр длина отрицателен, замена завершается в позиции (длина строки -длина).

Простая замена текста функцией substr_replace( ) продемонстрирована в следующем примере:

$favs = » ‘s favorite links»;

// Параметры «0, 0» означают, что заменяемый фрагмент начинается

// и завершается в первой позиции строки.

$favs — substr_replace($favs, $name, 0, 0);

Alessia’s favorite links

Преобразование строк и файлов к формату HTML и наоборот

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

Преобразование текста в HTML

Быстрое преобразование простого текста к формату web-браузера — весьма распространенная задача. В ее решении вам помогут функции, описанные в этом разделе.

Функция nl2br( ) заменяет все символы новой строки (\n) эквивалентными конструкциями HTML
.

Синтаксис функции nl2br( ):

string nl2br (string строка)

Символы новой строки могут быть как видимыми (то есть явно включенными в строку), так и невидимыми (например, введенными в редакторе). В следующем примере текстовая строка преобразуется в формат HTML посредством замены символов \n разрывами строк:

// Текстовая строка, отображаемая в редакторе.

Party Sauce recipe:

1 can stewed tomatoes

3 tablespoons fresh lemon juice

Stir together, server cold.»;

// Преобразовать символы новой строки в

При последующем выводе $html_recipe браузеру будет передан следующий текст в формате HTML:

Party Sauce recipe:

1 can stewed tomatoes

3 tablespoons fresh lemon juice

Stir together, server cold.

Функция htmlentities( ) преобразует символы в эквивалентные конструкции HTML. Синтаксис функции htmlentities:

string htmlentities (string строка)

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

$user_input = «The cookbook, entitled Cafe Francaise’ costs преобразуется в >.

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

Следующий пример демонстрирует удаление потенциально опасных символов функцией htmlspeclalchars( ):

$user_input = «I just can’t get «enough» of PHP & those fabulous cooking recipes!»;

// $conv_input = «I just can’t > of PHP &amp those fabulous cooking

Если функция htmlspecialchars( ) используется в сочетании с nl2br( ), то последнюю следует вызывать после htmlspecialchars( ). В противном случае конструкции
, сгенерированные при вызове nl2br( ), преобразуются в видимые символы.

Функция get_html_translation_table( ) обеспечивает удобные средства преобразования текста в эквиваленты HTML Синтаксис функции get_htrril_translation_table( ):

string get_html_translation_table (int таблица)

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

Параметр таблица принимает одно из двух значений:

В следующем примере функция get_html_translation_table( ) используется при преобразовании текста в код HTML:

$string = «La pasta e il piatto piu amato in Italia»;

print strtr($string, $translate);

// Специальные символы преобразуются в конструкции HTML

// и правильно отображаются в браузере.

Кстати, функция array_flip( ) позволяет провести преобразование текста в HTML в обратном направлении и восстановить исходный текст. Предположим, что вместо вывода результата strtr( ) в предыдущем примере мы присвоили его переменной $translated string.

В следующем примере исходный текст восстанавливается функцией array_flip( ):

$translated_string — «La pasta é il piatto piú amato in Italia»;

$original_string = strtr($translated_string, $translate);

// $original_string = «La pasta e il piatto piu amato in Italia»;

Функция strtr( ) транслирует строку, то есть заменяет в ней все символы, входящие в строку источник, соответствующими символами строки приемник. Синтаксис функции strtr( ):

string strtr (string строка, string источник, string приемник)

Если строки источник и приемник имеют разную длину, длинная строка усекается до размеров короткой строки.

Существует альтернативный синтаксис вызова strtr( ) с двумя параметрами; в этом случае второй параметр содержит ассоциативный массив, ключи которого соответствуют заменяемым подстрокам, а значения — заменяющим подстрокам. В следующем примере теги HTML заменяются XML-подобными конструкциями:

Today In PHP-Powered News»

print strtr($string, $source);

// Выводится строка » Today in PHP-Powered News «

Преобразование HTML в простой текст

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

Функция strip_tags( ) удаляет из строки все теги HTML и PHP, оставляяв ней только текст. Синтаксис функции strip_tags( ):

string strip_tags (string строка [, string разрешенные_тerи])

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

Ниже приведен пример удаления из строки всех тегов HTML функцией strip_tags( ):

$user_input = «I just love PHP and gourment recipes!»;

// $stripped_input = «I just love PHP and gourmet recipes!»;

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

$strip_input = strip_tags ($user_input, «»);

// $strip_input = «I love to eat!!»;

Удаление тегов из текста также производится функцией fgetss( ), описанной в главе 7.

Хотя функция get_meta_tags( ) и не имеет прямого отношения к преобразованию текста, зто весьма полезная функция, о которой следует упомянуть. Синтаксис функции get_meta_tags( ):

array get_meta_tags (string имя_файла/URL [, int включение_пути])

Функция get_meta_tags( ) предназначена для поиска в файле HTML тегов МЕТА.

Теги МЕТА содержат информацию о странице, используемую главным образом поисковыми системами. Эти теги находятся внутри пары тегов . . Применение тегов МЕТА продемонстрировано в следующем фрагменте (назовем его example.html, поскольку он будет использоваться в листинге 8.2):

Функция get_meta_tags( ) ищет в заголовке документа теги, начинающиеся словом МЕТА, и сохраняет имена тегов и их содержимое в ассоциативном массиве. В листинге 8.2 продемонстрировано применение этой функции к файлу example.html.

Листинг 8.2. Извлечение тегов МЕТА из файла HTML функцией get_meta_tags( )

// Переменная $meta_tags содержит массив со следующей информацией:

// $meta_tags[«keywords»] = «gourmet. PHP. food. code, recipes, chef, programming. Web»:

// $meta_tags[«description»] = «PHP Recipes provides savvy readers with the latest in PHP

programming and gourmet cuisine»;

// $meta_tags[«author»] = «WJ Gilmore»;

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

Теги МЕТА и их использование превосходно описаны в статье Джо Берна (Joe Burn) «So, You Want a Meta Command, Huh?» на сайте HTML Goodies: http://htmlgoodies.earthweb.com/tutors/meta.html .

Преобразование строки к верхнему и нижнему регистру

В PHP существует четыре функции, предназначенных для изменения регистра строки:

Все эти функции подробно описаны ниже.

Функция strtolower( ) преобразует все алфавитные символы строки к нижнему регистру. Синтаксис функции strtolower( ):

string strtolower(string строка)

Неалфавитные символы функцией не изменяются. Преобразование строки к нижнему регистру функцией strtolower( ) продемонстрировано в следующем примере:

$sentence = «COOKING and PROGRAMMING PHP are my TWO favorite pastimes!»;

// После вызова функции $sentence содержит строку

// «cooking and programming php are my two favorite pastimes!»

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

string strtoupper (string строка)

Неалфавитные символы функцией не изменяются. Преобразование строки к верхнему регистру функцией strtoupper( ) продемонстрировано в следующем примере:

$sentence = «cooking and programming PHP are my two favorite pastimes!»;

// После вызова функции $sentence содержит строку

// «COOKING AND PROGRAMMING PHP ARE MY TWO FAVORITE PASTIMES!»

Функция ucfirst( ) преобразует к верхнему регистру первый символ строки — при условии, что он является алфавитным символом. Синтаксис функции ucfirst( ):

string ucfirst (string строка)

Неалфавитные символы функцией не изменяются. Преобразование первого символа строки функцией ucfirst( ) продемонстрировано в следующем примере:

// После вызова функции $sentence содержит строку

// «Cooking and programming PHP are mу two favorite pastimes!»

Функция ucwords( ) преобразует к верхнему регистру первую букву каждого слова в строке. Синтаксис функции ucwords( ):

string ucwords (string строка»)

Неалфавитные символы функцией не изменяются. «Слово» определяется как последовательность символов, отделенная от других элементов строки пробелами. В следующем примере продемонстрировано преобразование первых символов слов функцией ucwords( ):

$sentence = «cooking and programming PHP are my two favorite pastimes!»;

// После вызова функции $sentence содержит строку

// «Cooking And Programming PHP Are My Two Favorite Pastimes!»

Проект: идентификация браузера

Каждый программист, пытающийся создать удобный web-сайт, должен учитывать различия в форматировании страниц при просмотре сайта в разных браузерах и операционных системах. Хотя консорциум W3 (http://www.w3.org) продолжает публиковать стандарты, которых должны придерживаться программисты при создании web-приложений, разработчики браузеров любят дополнять эти стандарты своими маленькими «усовершенствованиями», что в конечном счете вызывает хаос и путаницу. Разработчики часто решают эту проблему, создавая разные страницы для каждого типа браузера и операционной системы — при этом объем работы значительно увеличивается, но зато итоговый сайт идеально подходит для любого пользователя. Результат — хорошая репутация сайта и уверенность в том, что пользователь посетит его снова.

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

Приведенный ниже проект (sniffer.php) показывает, как использовать функции PHP для работы с регулярными выражениям с целью получения информации по запросам. Программа определяет тип и версию браузера и операционной системы, после чего выводит полученную информацию в окне браузера. Но прежде чем переходить к непосредственному анализу программы, я хочу представить один из главных ее компонентов — стандартную переменную PHP $HTTP_USER_AGENT. В этой переменной в строковом формате хранятся различные сведения о браузере и операционной системе пользователя — именно то, что нас интересует. Эту информацию можно легко вывести на экран всего одной командой:

При работе в Internet Explorer 5.0 на компьютере с Windows 98 результат будет выглядеть так:

Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)

Для Netscape Navigator 4.75 выводятся следующие данные:

Mozilla/4.75 (Win98; U)

Sniffer.php извлекает необходимые данные из $HTTP_USER_AGENT при помощи функций обработки строк и регулярных выражений. Алгоритм программы на псевдокоде:

  • Определить две функции для идентификации браузера и операционной системы: browser_info( ) и opsys_info( ). Начнем с псевдокода функции browser_info( ).
  • Определить тип браузера, используя функцию егед( ). Хотя эта функция работает медленнее упрощенных строковых функций типа strstr( ), в данном случае она удобнее, поскольку регулярное выражение позволяет определить версию браузера.
  • Воспользоваться конструкцией if/elseif для идентификации следующих браузеров и их версий: Internet Explorer, Opera, Netscape и браузер неизвестного типа.
  • Вернуть информацию о типе и версии браузера в виде массива.
  • Функция opsys_info( ) определяет тип операционной системы. На этот раз используется функция strstr( ), поскольку тип ОС определяется и без применения регулярных выражений.
  • Воспользоваться конструкцией if/elseif для идентификации следующих систем: Windows, Linux, UNIX, Macintosh и неизвестная операционная система.
  • Вернуть информацию об операционной системе.

Листинг 8.3. Идентификация типа браузера и операционной системы клиента

Вот и все! Например, если пользователь работает в браузере Netscape 4.75 на компьютере с системой Windows, будет выведен следующий результат:

Browser Type: Netscape

Browser Version: 4.75

Operating System: Windows

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

Итоги

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

  • общие сведения о регулярных выражениях в стилях POSIX и Perl;
  • стандартные функции PHP для работы с регулярными выражениями;
  • изменение длины строки;
  • определение длины строки;
  • альтернативные функции PHP для обработки строковой информации;
  • преобразование простого текста в HTML и наоборот;
  • изменение регистра символов в строках.

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

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

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

А эти строки не соответствуют указанным требованиям:

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

Для сокращенного обозначения регулярных выражений в английском языке применяется термин . Регулярные выражения представляют собой шаблоны для согласования со строками, содержащие специальные подстановочные символы, которые могут быть согласованы с целыми фрагментами целевой строки. Язык PHP позволяет применять два широких класса регулярных выражений: регулярные выражения, совместимые со стандартом POSIX (называемые расширенными), и обычные регулярные выражения, совместимые с языком Perl. Различия между этими классами в основном касаются синтаксиса, но имеются также некоторые функциональные различия.

В конечном итоге регулярные выражения в стиле POSIX явились итогом развития средств сопоставления с шаблонами регулярных выражений, используемых в интерпретаторах Unix с интерфейсом командной строки, а регулярные выражения, совместимые с языком Perl, в большей степени напоминают соответствующие средства указанного языка. Любой разработчик, которому предстоит выполнить хоть сколько-нибудь существенный объем программирования в среде веб, рано или поздно будет вынужден воспользоваться регулярными выражениями.

Начиная с версии PHP 5.3.0 функции для работы с регулярными выражениями в стиле POSIX являются устаревшими, поэтому далее мы будем рассматривать регулярные выражения в стиле Perl.

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

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

Шаблоны регулярных выражений, совместимых с языком Perl, всегда начинаются и оканчиваются одним конкретным символом, который должен быть одинаковым и в начале и в конце. Этот символ отмечает начало и конец шаблона. В соответствии с общепринятым соглашением для этой цели чаще всего используется символ /, но при желании может также применяться другой символ. Следующий шаблон, совместимый с языком Perl: /pattern/, согласуется с любой строкой, которая содержит в себе строку (вернее, подстроку) «pattern».

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

Специальный символ ^ согласуется только с началом строки, а специальный символ $ — только с концом строки.

Специальный символ . согласуется с любым символом.

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

Набор символов, заключенный в квадратные скобки, согласуется с любым из символов этого набора. Например, шаблон [ab] согласуется и с буквой a, и с буквой b. В квадратных скобках можно также определить диапазон символов с использованием дефиса. Например, шаблон [a-c] согласуется с буквой a, b или c.

Специальные символы, отмеченные знаком переключения режима обработки в виде обратной косой черты (\), теряют свое специальное значение и сопоставляются непосредственно, как обычные символы.

Если рассматриваемый символ не является специальным, то шаблон в стиле Perl последовательно согласует символы. Например, шаблон /abc/ согласуется с любой строкой, которая содержит подстроку «abc»

Любой шаблон, за которым следует символ ? (вопросительный знак), означает: «Выполнить согласование конструкции, предшествующей этому символу, нуль или один раз».

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

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

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

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

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

Специальные символы регулярных выражений PHP

Классы символов
[. ] Любой из символов, указанных в скобках
[^. ] Любой из символов, не указанных в скобках
. Любой символ, кроме перевода строки или другого разделителя Unicode-строки
\w Любой символ, образующий «слово»
\W Любой символ, не являющийся текстовым символом
\s Любой пробельный символ из набора Unicode
\S Любой непробельный символ из набора Unicode. Обратите внимание, что символы \w и \S — это не одно и то же
\d Любые ASCII-цифры. Эквивалентно [0-9]
\D Любой символ, отличный от ASCII-цифр. Эквивалентно [^0-9]
Символы повторения
Соответствует предшествующему шаблону, повторенному не менее n и не более m раз
Соответствует предшествующему шаблону, повторенному n или более раз
Соответствует в точности n экземплярам предшествующего шаблона
? Соответствует нулю или одному экземпляру предшествующего шаблона; предшествующий шаблон является необязательным. Эквивалентно
+ Соответствует одному или более экземплярам предшествующего шаблона. Эквивалентно
* Соответствует нулю или более экземплярам предшествующего шаблона. Эквивалентно
Символы регулярных выражений выбора
| Соответствует либо подвыражению слева, либо подвыражению справа (аналог логической операции ИЛИ).
(. ) Группировка. Группирует элементы в единое целое, которое может использоваться с символами *, +, ?, | и т.п. Также запоминает символы, соответствующие этой группе для использования в последующих ссылках.
(. ) Только группировка. Группирует элементы в единое целое, но не запоминает символы, соответствующие этой группе.
Якорные символы регулярных выражений
^ Соответствует началу строкового выражения или началу строки при многострочном поиске.
$ Соответствует концу строкового выражения или концу строки при многострочном поиске.
\b Соответствует границе слова, т.е. соответствует позиции между символом \w и символом \W или между символом \w и началом или концом строки.
\B Соответствует позиции, не являющейся границей слов.
(?=p) Позитивная опережающая проверка на последующие символы. Требует, чтобы последующие символы соответствовали шаблону p, но не включает эти символы в найденную строку.
(?!p) Негативная опережающая проверка на последующие символы. Требует, чтобы следующие символы не соответствовали шаблону p.
\A начало данных (независимо от многострочного режима)
\Z конец данных либо позиция перед последним переводом строки (независимо от многострочного режима)
Флаги (указываются в конце рег. выражения)
i Указывает, что поиск по шаблону должен быть нечувствителен к регистру символов.
m Многострочный режим поиска (multiline).
s Если данный модификатор используется, метасимвол «точка» в шаблоне соответствует всем символам, включая перевод строк.
x Если используется данный модификатор, неэкранированные пробелы, символы табуляции и пустой строки будут проигнорированы в шаблоне, если они не являются частью символьного класса.

Общие сведения о функциях, совместимых с языком Perl, приведены в таблице ниже:

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

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

В случае успешного согласования переменная типа «массив» содержит следующие элементы: первым элементом является вся согласованная подстрока, а последующие элементы содержат части, соответствующие заключенным в круглые скобки подвыражениям шаблона. Начиная с версии PHP 4.3.0 предусмотрена также возможность задать необязательный флаг PREG_OFFSET_CAPTURE. Этот флаг вынуждает функцию preg_match() возвращать в указанном массиве в расчете на каждое согласование по одному двухэлементному массиву, состоящему из самих результатов согласования и информации о смещении, с которого было начато успешное согласование.

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

Принимает в качестве первого параметра шаблон регулярного выражения и второго параметра — строку, с которой должно быть выполнено согласование. Возвращает массив, содержащий результаты разбиения строки на подстроки в местах вхождения разграничительных строк, согласующихся с шаблоном. Необязательный третий параметр (с обозначением предельного количества) указывает, на какое количество подстрок должна быть разбита строка, прежде чем будет возвращен полученный список; значение -1 в позиции третьего параметра указывает на то, что предел не устанавливается. В качестве необязательного четвертого параметра может быть задан флаг PREG_SPLIT_NO_EMPTY (вынуждающий функцию возвращать только непустые части), PREG_SPLIT_DELIM_CAPTURE (которое требует возврата всех подстрок, соответствующих заключенным в круглые скобки выражениям в шаблоне разграничителя) или PREG_OFFSET_CAPTURE.

Функция Описание
preg_match()
preg_match_all()
preg_split()
preg_replace() Принимает в качестве параметров шаблон, строку замены и строку, в которой должны быть внесены изменения. Возвращает модифицированную строку, в которой вместо каждой подстроки, согласованной с шаблоном, подставлена строка замены. Необязательный параметр с обозначением предельного количества определяет, сколько должно быть выполнено замен (как в функции preg_split())
preg_replace_callback() Эта функция аналогична функции preg_repiace(), за исключением того, что вторым параметром является имя функции обратного вызова, а не строка замены. Эта функция должна возвращать строки, предназначенные для использования в качестве замены
preg_grep() Принимает в качестве параметров шаблон и массив и возвращает массив, состоящий из элементов входного массива, который сопоставляется с шаблоном. Значения, перешедшие из старого массива в новый массив, имеют такие же ключи, как и соответствующие элементы исходного массива
preg_quote() Функция специального назначения, предназначенная для вставки знаков переключения на другой режим обработки в строки, которые предназначены для использования в качестве шаблонов регулярных выражений. Для этой функции требуется единственный параметр—строка, в которую должны быть вставлены знаки переключения; возвращаемым значением является та же строка, в которой перед каждым специальным символом регулярного выражения вставлена обратная косая черта (знак переключения)

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

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

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

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

Код PHP «; // Шаблон регулярного выражения $pattern = ‘/(\d+)[\s|\(|-]*([\d]<3,>)[\s|\)|-]*([\d|-]+)/’; preg_match_all($pattern, $str, $arr, PREG_SET_ORDER); foreach ($arr as $entry) < echo "

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

Использование регулярных выражений для поиска телефонных номеров

Я могу долго объяснять принцип работы представленного в примере регулярного выражения, но я лучше покажу:

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

Пример: программа извлечения ссылок

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

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

Основное регулярное выражение

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

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

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

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

Обратите внимание на то, что разрабатываемый шаблон еще не предназначен для использования в работоспособном коде PHP; в данном случае создается черновой вариант выражения, которое должно быть вставлено в код PHP позднее. На обычном языке первое черновое определение дескриптора анкора можно описать как состоящее из левой угловой скобки, за которой следует буква «a», затем — пробел, вслед за ним — строка «href=», знак двойной кавычки, произвольное количество символов, отличных от знаков кавычки, заключительный знак кавычки и, наконец, правая угловая скоба. После его составления все выражение заключается в пару символов косой черты, которые служат для машины обработки регулярных выражений указанием на то, где начинается и оканчивается выражение.

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

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

В качестве текста анкора допускается использовать любой текст, который занимает на странице место вплоть до заключительного дескриптора анкора, поэтому создается класс символов, который включает любые символы, кроме правой угловой скобой ([^>]*), и указывает, что данные символы могут присутствовать в количестве от нуля и больше. Наконец, вводится субшаблон для сопоставления с закрывающим дескриптором анкора ( ).

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

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

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

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

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

Принять в качестве параметра заданный URL.

Открыть соединение HTTP с помощью указанного URL и получить информационное наполнение страницы в виде строки.

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

Вывести на экран все пары извлеченных подстрок (состоящие из целевого URL и текста анкора).

В примере ниже показана полная структура целевой страницы включая функцию print_links():

Простая программа поиска ссылок на PHP

Задача разработки этой функции проще, чем кажется на первый взгляд, поскольку в языке PHP уже предусмотрены многие ее составляющие. В частности, не требуется предусматривать каких-либо особых действий по созданию соединения HTTP для загрузки веб-страницы, поскольку функция fopen() принимает URL в качестве параметра и выполняет все необходимое. Поэтому достаточно после вызова функции fopen() с указанным в ней URL считывать символы до тех пор, пока поступление этих символов не прекратится, добавляя полученные данные к создаваемой строке.

Обработка в цикле содержимого HTML-страницы обеспечивается с помощью функции preg_match_all(). В этой функции шаблон регулярного выражения применяется максимально возможное количество раз, после каждого использования обработка строки начинается непосредственно вслед за тем участком, где перед этим было обнаружено совпадение с шаблоном, и результаты поиска сохраняются в массиве $match_array. Здесь мы решили применить структуру массива, упорядоченную в соответствии с флажком PREG_SET_ORDER. Это означает, что каждая запись в массиве верхнего уровня представляет собой часть, соответствующую результатам конкретного согласования с шаблоном в текущей итерации, а не часть, полученную в результате всех согласований.

Очередной блог фрилансера

коротко и полезно о веб-разработке

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

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

Введение в регулярные выражения

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

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

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

Теперь, выше этой строки, добавьте этот код:

Сохраните файл search.php, и откройте style.css. Добавьте следующую строку:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Комплексная проверка пароля

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

Текстовое поле должно содержать как минимум один символ верхнего регистра, один нижнего регистра и одну цифру.

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

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

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

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

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

Перевод статьи “15 PHP regular expressions for web developers”, автор Jean-Baptiste Jung

Рассказать друзьям

Понравилась статья? Лучший способ сказать спасибо — поделиться ссылкой в социальных сетях:

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

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

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

  • Функция preg_match(string pattern, string subject, array matches) — данная функция ищет совпадения в строке subject регулярному выражению pattern. Первое найденное совпадение помещается в массив matches. Обратите внимание, что эта функция ищет только первое совпадение. Второе, третье и так далее она не ищет! Массив matches будет таким:
    • Первый элемент содержит всю совпавшую часть строки в целом.
    • Второй элемент содержит часть строки, совпавшей с первым субпаттерном (что такое субпаттерны будет разобрано в одной из следующих статей).
    • Третий элемент содержит часть строки, совпавшей с вторым субпаттерном.
    • И так далее.

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

  • Функция preg_match_all(string pattern, string subject, array matches) — полный аналог функции preg_match(), но здесь поиск совпадений продолжается и после первого найденного. То есть если функция preg_match() останавливает свою работу после первого найденного совпадения, то функция preg_match_all() идёт дальше. Возвращает эта функция — количество совпадений (разумеется, их может быть больше 1-го).
  • Функция preg_replace(mixed pattern, mixed replacement, mixed subject, int limit). Очень полезная функция, которая в строке subject заменяет строки, соответствующие pattern, на replacement. Количество замен задаётся параметром limit. Если данный параметр не указан (а он является необязательным), то будет проведена замена всех найденных совпадений.

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

В результате, как Вы и догадались появится строка: «E-mail найден«. В данном примере написано регулярное выражение, которое Вы пока понимать не должны. Уже начиная со следующей статьи, мы с Вами будем учиться составлять регулярные выражения, а пока просто примите как должное: регулярное выражение в примере ищет e-mail в заданной строке.

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

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

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

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

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

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

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

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

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

    А не подскажите в чем может быть проблема: Писал для сайта функцию поиска и все вроде работало нормально, но заметил что если в поисковом запросе есть-(дефис) то поиск не работает: preg_match(«/$arr[$i]/i»,$value[‘title’])) вот основная функция для поиска, где $arr[i] — поисковой запрос

    Поставьте перед preg_match() вот это: $arr[$i] = quotemeta($arr[$i]);

    Спасибо, идею понял, но почему то не сработало все равно

    preg_match()

    Синтаксис:

    preg_match(pattern, string_name[,matches[, flags[, offset]]])

    Поддерживается следующими версиями PHP:

    Описание функции:

    Функция preg_match проверяет есть ли в строке совпадения с регулярным выражением. Функция возвращает три возможных значения:
    0 — если совпадений не найдено,
    1 — если соdпадение найдено (после нахождения первого совпадения работа функции прекращается),
    false — если произошла ошибка.

    Обязательный аргумент. Регулярное выражение (шаблон поиска)

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

    string matches Необязательный аргумент. Если совпадение есть, то массив $matches будет заполнен значениями. В $matches[0] будут помещена часть строки полностью соответствующая шаблону, $matches[1] будет содержать текст соответствующей первой маске, $matches[2] текст второй маски и так далее. array flags

    Необязательный аргумент. Данный аргумент может содержать только одно значение PREG_OFFSET_CAPTURE.

    Если этот флаг указан, то в массиве matches будет возвращен массив массивов, где под индексом «0» в первом вложенном массиве будет находиться совпавшая строка, а под индексом «1» ее смещение от начала строки.

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

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

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

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

    Примеры:

    Пример 1:

    В этом примере проверяется есть ли в строковом выражении символ «P» и следом идущая за этим символом цифра.

    $arr_str = preg_match(«/P[0-9]/», «PHP5 is a useful language»);
    print ($arr_str);
    ?>

    Пример 2:

    $arr_str = preg_match(«/P[0-9]/», «PHP5 is a useful language», $match_arr);
    print_r ($match_arr);
    ?>

    Пример 3:

    В этом примере показано использование флага PREG_OFFSET_CAPTURE

    $arr_str = preg_match(«/P[0-9]/», «PHP5 is a useful language», $match_arr, PREG_OFFSET_CAPTURE);
    print_r ($match_arr);
    ?>

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

    Пример 4:

    В этом примере используем аргумент offset

    $arr_str = preg_match(«/P[0-9]/», «PHP5 is a useful language», $match_arr, PREG_OFFSET_CAPTURE,1);
    print_r ($match_arr);
    ?>

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

    если начать поиск с 4 позиции, то будет возвращен пустой массив

    $arr_str = preg_match(«/P[0-9]/», «PHP5 is a useful language», $match_arr, PREG_OFFSET_CAPTURE,4);
    print_r ($match_arr);
    ?>

    Тест на знание функции preg_match()

    1. Выберите верный вариант ответа.

    $arr_str = preg_match(«/P[0-9]», «PHP5 is a useful language»);
    var_dump ($arr_str);
    ?>

    int(0) int(1) bool(false)

    2. Выберите верный вариант ответа.

    $arr_str = preg_match(«/P[0-9]/», «PHP5 is a useful language», $match_arr, PREG_OFFSET_CAPTURE,1);
    print_r ($arr_str);
    ?>

    Array ( [0] => Array ( [0] => P5 [1] => 2 ) ) int(1) 1 «Ничего»

    3. Выберите верный вариант ответа.

    $arr_str = preg_match(«/P[0-9]/», «PHP5 is a useful language», $match_arr, PREG_OFFSET_CAPTURE,1);
    print_r ($match_arr);
    ?>

    Array ( [0] => Array ( [0] => P5 [1] => 2 ) ) int(1) 1 «Ничего»

    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().

    Уроки PHP – регулярные выражения с примерами

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

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

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

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

    Типы регулярных выражений

    Существует 2 типа регулярных выражений:

    • Perl совместимый
    • POSIX расширенный

    Perl совместимые функции – это такие как preg_match , preg_replace , а версии POSIX – такие как ereg , eregi . Учтите, что последние функции считаются устаревшими в PHP 5.3.0 и были удалены в PHP 7. Поэтому мы будем использовать только Perl совместимые функции. Важно знать, что при использовании Perl-совместимых регулярных выражений, такое выражение должно быть заключено в разделители, например, косую черту ( / ).

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

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

    • Обычные символы, которые следуют один за другим, например, hello
    • Индикаторы начала и окончания строки в виде ^ и $
    • Индикаторы подсчета, такие как + , * , ?
    • Логические операторы, такие как |
    • Группирующие операторы, такие как <> , () , []

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

    Код PHP для проверки электронной почты с использованием Perl-совместимого регулярного выражения выглядит следующим образом:

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

    Регулярное выражение (шаблон) Проходит проверку (объект) Не проходит проверку (объект) Комментарий
    world Hello world Hello Ivan Проходит, если шаблон присутствует где-либо в объекте
    ^world world class Hello world Проходит, если шаблон присутствует в начале объекта
    world$ Hello world world class Проходит, если шаблон присутствует в конце объекта
    world/i This WoRLd Hello Ivan Выполняет поиск в нечувствительном к регистру режиме
    ^world$ world Hello world Строка содержит только «world»
    world* worl, world, worlddd wor Присутствует 0 или больше «d» после «worl»
    world+ world, worlddd worl Присутствует по крайней мере одна «d» после «worl»
    world? worl, world, worly wor, wory Присутствует 0 или 1 «d» после «worl»
    world world worly Присутствует одна «d» после «worl»
    world world, worlddd worly Присутствует одна или больше «d» после «worl»
    world worldd, worlddd world Присутствует 2 или 3 «d» после «worl»
    wo(rld)* wo, world, worldold wa Присутствует 0 или больше «rld» после «wo»
    earth|world earth, world sun Строка содержит «earth» или «world»
    w.rld world, wwrld wrld Содержит любой символ вместо точки
    ^.<5>$ world, earth sun Строка содержит ровно 5 символов
    [abc] abc, bbaccc sun В строке есть «a», или «b» или «c»
    [a-z] world WORLD В строке есть любые строчные буквы
    [a-zA-Z] world, WORLD, Worl12 123 В строке есть любые строчные или прописные буквы
    [^wW] earth w, W Фактический символ не может быть «w» или «W»

    Теперь перейдем к более сложному регулярному выражению с подробным объяснением.

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

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

    1) Проверка имени пользователя с помощью регулярного выражения
    Начнем с проверки имени пользователя. Если у вас есть форма регистрации, вам понадобится проверять на правильность имена пользователей. Предположим, вы не хотите, чтобы в имени были какие-либо специальные символы, кроме « _.- » и, конечно, имя должно содержать буквы и возможно цифры. Кроме того, вам может понадобиться контролировать длину имени пользователя, например от 4 до 20 символов.

    Сначала нам нужно определить доступные символы. Это можно реализовать с помощью следующего кода:

    После этого нам нужно ограничить количество символов следующим кодом:

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

    В случае Perl-совместимого регулярного выражения заключите его символами ‘ / ‘. Итоговый PHP-код выглядит так:

    2) Проверка шестнадцатеричного кода цвета регулярным выражением
    Шестнадцатеричный код цвета выглядит так: #5A332C , также допустимо использование краткой формы, например #C5F . В обоих случаях код цвета начинается с # и затем идут ровно 3 или 6 цифр или букв от a до f.

    Итак, проверяем начало кода:

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

    После этого проверяем допустимую длину кода (она может быть либо 3, либо 6). Полный код регулярного выражения выйдет следующим:

    Здесь мы используем логический оператор, чтобы сначала проверить код вида #123 , а затем код вида #123456 . Итоговый PHP-код проверки регулярным выражением выглядит так:

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

    Как мы можем видеть, символ @ является обязательным элементом в адресе электронной почты. Помимо этого должен быть какой-то набор символов до и после этого элемента. Точнее, после него должно идти допустимое доменное имя.

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

    Доменное имя всегда имеет, скажем, имя и tld (top-level domain) – т.е, доменную зону. Доменная зона – это .com , .ua , .info и тому подобное. Это означает, что шаблон регулярного выражения для домена будет выглядеть так:

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

    В коде PHP эта проверка будет выглядеть следующим образом:

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

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

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

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

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

    В 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

    Регулярное выражение (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, которая делает все квантификаторы «не жадными» по умолчанию и «жадными», если после них идет знак вопроса.

    Илон Маск рекомендует:  Windows forms современная модель программирования для создания gui приложений
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL