
Регулярные выражения — это специализированный язык поиска и осуществление манипуляций с подстроками в тексте. Синтаксис регулярных выражений является достаточно сложным и его изучение требует серьезных усилий.
Базовый синтаксис и создание регулярных выражений
В настоящий момент существует несколько диалектов регулярных выражений. В данный момент будет рассмотрен синтаксис Perl-совместимых регулярных выражений, как самого распространенного и развитого диалекта.
Регулярное выражение — это шаблон, применяемый к заданному тексту слева направо. Большая часть символов сохраняет свое значение в шаблоне и означает совпадение с соответствующим символом. Так регулярное выражение содержащее обычный текст, например "грам", соответствует строке, содержащей указанную подстроку, например "программирование".
В Perl для регулярного выражения обязательно задание границ. Так приведенный выше пример можно написать следующим образом:
"/грам/"
Символ / применяется для задания границ регулярного выражения, т.е регулярное выражение действует до тех пор, пока не встретит второй символ прямого слеша(/). После регулярного выражения следуют модефикаторы шаблона — инструкции, действующие на все регулярное выражение. Мы рассмотрим только один модефикатор i. При его использовании поиск по регулярному выражению осуществляется без учета регистра. Так рассмотренный выше пример можно записать следующим образом:
"/грам/i"
Данное выражение будет соответствовать как строке "программирование", так и строке "ПРОГРАММИРОВАНИЕ".
Остальными модефикаторами можно ознакомиться в документации РНР, которая доступна для свободной загрузки с адреса http://www.php.net. Данный раздел документации переведен на русский язык.
Рассмотренное регулярное выражение осуществляет поиск по всему тексту, но чаще следует привязать регулярное выражение к началу слова, т.е. чтобы регулярное выражение "/грам/i" соответствовало строке, начинающейсясо слова "граммпластинка", но не подходило бы слову "программировние". Для этого используется символ ^, соответствующий началу строки:
"/^грам/i"
Знак доллара $ означает конец строки:
"/^граммпластинка$/i"
Это регулярное выражение соответствует любой строке "граммпластинка", но не подходит строке "граммпластинка — это вам не программирование", т.к. после искомого слова идет текст.
Регулярное выражение
"/^$/i"
соответствует пустой строке.
В поисковой строке может понадобиться найти подстроку, содержащую символ /, который у нас используется для обозначения границ. В этом случае необходимо прибегнуть к экранированию этого символа с помощью символа обратного слеша (\). Так у подстроки "Программирование/ РНР" регулярное выражение выглядит так:
"/программирование\ /php/i"
Eсли символ / встречается часто в поисковой строке (например, в HTML-тексте), то можно изменить границы регулярного выражения, в качестве них может выступать любой другой символ, например, следующее регулярное выражение эквивалентно только что рассмотренному:
"|программирование/php|i"
Использование символа вертикальной черты (|) в качестве границы слова не всегда приемлемо, т.к. он может присутствовать в регулярном выражении для задания альтернативных масок:
"/abc|абв/"
Этому регулярнову выражению соответствует любая строка, содержащая подстроки "abc" или "абв". Вертикальную черту удобно применять при проверке расширений и имен файлов, зон доменных имен и т.д. К примеру, следующее регулярное выражение проверяет, содержатся ли в строке подстроки "ru", "com" или "net":
"/ru|com|net/"
Это выражение соответствует любой строке, которая содержит подстроку abc.
Подстроки регулярных выражениях можно групперовать при помощи скобок:
"/домен - (ru|com|net)/i"
Это регулярное выражение будет соответствовать строке вида "домен - ru", вместо ru может быть как com, так и net. Если необходимо использовать скобки как часть искомой строки, их следует экранировать. Так для поиска подстроки "программирование (РНР)" следует использовать следующее регулярное выражение:
"/программирование \(РНР\)i"
Скобки при программировании в РНР и Perl имеют еще одно значение помимо группировки символов. Все найденные в скобках выражения сохраняются интерпретатором, и к ним можно обратиться при замене или поиске по номеру скобки \\1, \\2 и т.д.
Для задания класса символов используются квадратные скобки ([ ]).Они ограничивают поиск теми символами, в которые они заключены:
"/[abc]/"
Этому регулярному выражению соответствует подстрока, содержащая один символ: либо а, либо b, либо с.
Так для создания регулярного выражения, соответствующего всем буквам русского алфавита, можно, конечно, перечислить все буквы в регулярном выражении. Это допустимо, но утомительно. Более коротко такое регулярное выражение можно записать следующим образом:
"/[а-Я ]/"
Данное выражение подходит всем буквам русского алфавита, поскольку любые два символа, разделяются дефисом, задают соответствие диапазону символов, находящихся между ними. Регулярное выражение "/[а-Я ]/" описывает символы как нижнего, так и верхнего регистров, поэтому более подробно это выражение можно записать так:
"/[а-яА-Я ]/"
Точно таким же образом задаются регулярные выражения, соответствующие цифре:
"/[0-9 ]/" или
"/[0123456789]/"
Оба выражения эквивалентны.
В регулярных выражениях действуют также экранирование, применение обратного слеша с определенными символами, что приводит к их специальной интерпретации:
\d— любая десятичная цифра;\D— любой символ, кроме десятичной цифры;\s— любой пробельный символ;\S— любой непробельный символ;\w—любой символ образующий "слово";\W— любой символ не образующий "слово";\t— символ табуляции;\f— конец файла;\n— символ перевода строки;\\— символ обратного слеша (\);\.— символ точки (".").
Рассмотренное выше регулярное выражение для числа можно записать следующим образом:
"/[\d]/"
Для исключения класса символов из поиска первым ставится символ ^, который в квадратных скобках действует уже не как указатель границы строки, а как отрицание:
"[^0-9]"
Это регулярное выражение отвечает любому символу, не содержащимуся в диапазоне 0-9, т.е. все что угодно, только не цифра.
Классы символов \d, \s и т.п. могут применяться в любой части регулярного выражения, а не только в квадратных скобках, т.е. вполне допустимо выражение вида "/\d/".
Выражения в квадратных скобках соответствует только одному символу и часто принимается совместно с так называемыми квантификаторами. Это символы ?, +, *, которые следуют сразу за символом и изменяют число вхождений конкретного символа в строку:
?— символ либо входит в строку один раз, либо вообще в нее не входит;- * —любое вхождение символа в строку, в том числе и 0;
+— одно или более вхождений символа в строку;
Символ ? позволяет сократить выражение вида
"программирование|программирование \/РНР/i"
до
"/программирование (РНР)?/i"
Метасимвол + обозначает один или несколько экземпляров элемента непосредственно предшествующего элемента, а * — любое количество экземпляров элемента, в том числе и нулевое. Так, если необходимо найти подстроку, содержащую одну или более цифр, следует воспользоваться выражением вида
"/[\d]+/"
Cимвол * используется для любого числа вхождений строки в подстроку, т.е. регулярное выражение
"/^[\d]*S/"
соответствует пустой строке, либо строке, содержащей только цифры, причем их колличество не ограничено.
Помимо круглых и квадратных скобок в регулярных выражениях так же применяются фигурные скобки {}. Они предназначены для указания чисел или диапазона чисел повторения элемента:
"xy{2}"— cоответствует строке"xyy";"xy{2,}"— соответствует строке, в которой захследует не менее двуху(может быть и больше);"xy{2,6}"— соответствует строке, в которой захследует от 2 до 6у.-
Для указания колличества вхождений не одиночного символа, а их последовательности, используются круглые скобки:
"x(yz){2,6}"— cоответствует строке, в которой захследует от двух до шести последовательностейyz;"x(yz)*"— cоответствует строке, в которой за х следует ноль и более последовательностейyz.
Функции для работы с регулярными выражениями
preg_match(string pattern, string subject [, array matches [, int flags [, int offset]]])— осуществляет поиск в строке по регулярному выражению. Ищет в строкеsubjectсоответствие регулярному выражениюpattern. Если задан необязательный параметр matches, то результаты поиска помещаются в массив. Элемент$matches[0]будет содержать часть строки, соответствующей вхождению всего шаблона,$matches[1]— часть строки соответствующей первым круглым скобкам,$matches[2]— вторым и т.д. Необязательный флагflagможет принять единственное значениеPREG_OFFSET_CAPTURE, при указании которого изменяется формат возвращаемого массива$matches— каждое вхождение возвращается в виде массива, в нулевом элементе которого содержится найденная подстрока, а в первом — смещение. Поиск осуществляется слева направо, с начала строки. Дополнительный параметрoffsetможет быть использован для указания альтернативной начальной позиции для поиска. Функцияpreg_match()возвращает количество найденных соответствий. Это может быть 0(совпадения не найдены) и 1, посколькуpreg_match()прекращает свою работу после первого найденного совпадения.-
Пример1:
<?php
$str = "PHP один из лучших языков программирования для Web";
if (preg_match ("/php/i", $str))
{
echo("Соответствие найдено");
}
else
{
echo("Соответствие не найдено");
}
?>В окне веб-браузера это будет выглядеть ТАК.
Пример2:<?php
$str = "PHP один из лучших языков программирования для Web";
if (preg_match ("/\bweb\b/i", $str))
{
echo("Соответствие найдено");
}
else
{
echo("Соответствие не найдено");
}
?>В окне веб-браузера это будет выглядеть ТАК.
Пример3:<?php
// получаем www-адрес (имя хоста) из url
$url = "http://www.php.net/download.html";
preg_match("/^(http:\/\/)?([^\/]+)/i", $url, $matches);
$host = $matches[2];
echo("www-адрес: $host");
echo("<br>");
// получаем последние два сегмента имени хоста (доменное имя)
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
echo "доменное имя: {$matches[0]}\n";
?>В окне веб-браузера это будет выглядеть ТАК.
Если необходимо найти либо сосчитать все совпадения, следует воспользоваться функцией
preg_match_all(). preg_match_all(string pattern, string subject, array matches [, int flags [, int offset]])— ищет в строкеsubjecвсе совпадения с регулярным выражениемpatternи помещает результат в массив matches в порядке, определяемом комбинацией флаговflags. Так же как в случае функцииpreg_match(), можно задать смещениеoffset, начиная с которого будет осуществляться поиск в строкеsubjec.-
После нахождения первого соответствия последующие поиски будут осуществлться не с начала строки, а от конца последнего найденного вхождения.
Дополнительный параметр
flagsможет комбинировать следующие значения (использованиеPREG_PATTERN_ORDERодновременно сPREG_SET_ORDERбессмысленно): PREG_PATTERN_ORDER— если этот флаг установлен, результат будет упорядочен следующим образом: элемент$matches[0]содержит массив полных вхождений регулярных выражений, элемент$matches[1]хранит массив вхождений первых круглых скобок,$matches[2]— вторых и т.д. То есть если строка содержит три соответствия регулярному выражению, то подстроку для последнего соответствия всему регулярному выражению можно найти в элементе$matches[0] [3], а для первых круглых скобок данного соответствия — в элементе$matches[1] [3];PREG_SET_ORDER— если этот флаг установлен, результат будет упорядочен следующим образом: элемент$matches[0]содержит полный набор вхождений, элемент$matches[1]— второй набор вхождений и т.д. В таком случае массив$matches[0]содержит первый набор вхождений, а именно: элемент$matches[0][0]хранит первое вхождение всего регулярного выражения, элемент$matches[0][1]— первое вхождение первых круглых скобок,$matches[0][2]— вторых и т.д. Аналогично массив$matches[1]содержит второй набор вхождений, и так для каждого найденного набора;PREG_OFFSET_CAPTURE— в случае, если флаг указан, для каждой найденной подстроки будет указана ее позиция в исходной строке. Необходимо помнить, что данный флаг меняет формат возвращаемых данных: каждое вхождение возвращается в виде массива, в нулевом элементе которого содержится найденная подстрока, а в первом — смещение.-
<?php
$user_info = "<b>PHP</b> <br> один из лучших языков программирования для <b>Web</b>";
preg_match_all ("/<b>(.*)<\/b>/e", $user_info, $pat_array);
print $pat_array[0][0]. "<br>".$pat_array[0][l];
?>В окне веб-браузера это будет выглядеть ТАК.
Функция
preg_match()возвращает количество найденных вхождений шаблона (может быть нулем) либоfalse, если во время выполнения возникли какие-либо ошибки.Обобщением функций
preg_match()иpreg_match_all()является функцияpreg_grer(). array preg_grer(string pattern, array input [, int flags])— перебирает все элементы заданного массива и возвращает все элементы, в которых совпадает заданное регулярное выражение. Возвращает массив, состоящий из элементов массиваinput, которые соответствуют заданному регулярному выражениюpattern. Параметрflagsможет принимать единственное значениеPREG_GREP_INVERT, задание которого приводит к тому, что функция возвращает те элементы массива input, которые не соответствуют регулярному выражениюpattern.-
Пример:
<?php
$avto=array("Nissan", "Волга", "Ваз");
/*поиск элементов начинающихся на "в" зa которым следует один или несколько символов*/
$b_avto=preg_grep("/в(\w+)/i", $avto);
for ($х = 0; $x <sizeof($avto); $x++){
print $b_avto[$x]. "<br>";
}
?>В окне веб-браузера это будет выглядеть ТАК.
preg_replace (mixed pattern, mixed replacement, mixed subject [,int limit])— ищет в строкеsubjectсоответствия регулярному выражениюpattern, и заменяет их наreplacement. Необязательного параметрlimitзадает число соответствий, которые надо заменить. Если этот параметр не указан, или равен-1, то заменяются все найденные соответствия.-
Параметр
replacementможет содержать ссылки вода\\n. Каждая такая ссылка будет заменена на подстроку, соответствующуюnраз повторяющимся круглым скобкам,nможет принять значение от 0 до 99, причем ссылка на\\0соответствует вхождению всего шаблона. Выражения в круглых скобках нумеруются слева направо, начиная с единицы.Если во время выполнения функции были обнаружены совпадения с шаблоном, будет возвращено измененное значение
subjec, в противном случае будет возвращен исходный текстsubjec.Первые три параметра функции
preg_replace()могут быть одномерными массивами. В случае если массив использует ключи, при обработке массива они будут взяты в том порядке, в котором расположены в массиве.Если параметры
patternиreplacementявляются массивами,preg_replace()поочередно извлекает из обоих массивов по паре элементов и использует их для операции поиска и замены. Если массивreplacementсодержит больше элементов, чемpattern, вместо недостающих элементов для замены будут взяты пустые строки. В случае, еслиpatternявляется массивом, аreplacement— строкой, по каждому элементу массиваpatternбудет осуществлен поиски замена наpattern(шаблоном будут поочередно все элементы массива, в то время как строка замены остается фиксированной). Вариант, когдаpatternявляется строкой, аreplacement— массивом, не имеет смысла.Пример:
<?php
$str = "Февраль 23, 2009";
$pattern = "/(\w+) (\d+), (\d+)/i";
$replacement = "23 \${1} \$3";
print preg_replace($pattern, $replacement, $str);
?>В окне веб-браузера это будет выглядеть ТАК.
preg_replace_callback(mixed pattern, callback callback, mixed subject [, int limit])— осуществляет поиск по регулярному выражению и замену с использованием функции обратного вызова. Поведение этой функции во многом сходно сpreg_replace(), за исключением того, что вместо параметраreplacemenнеобходимо указать функциюcallback, которой в качестве входящего параметра передается массив найденных вхождений. Функция обратного вызоваcallbackвозвращает строку, в которой будет произведена замена.preg_split()— разбивает строку по регулярному выражению. Синтаксис функции:-
array preg_split (stringшаблон, string строка [, int порог [, int флаги]])Функция возвращает массив, состоящий из подстрок заданной строки строка, которая разбита по границам, соответствующим шаблону шаблон.
В случае если параметр порог указан, функция возвращает не более, чем порог подстроек, при его отсутствии или равенстве — 1 функция действует без ограничений. Последний параметр флаги может быть произвольной комбинацией следующих флагов (соединение происходит при помощи оператора
ИЛИ (|)): PREG_SLIT_NO_EMPTY— если этот флаг указан, функцияpreg_split()вернет только пустые подстроки;PREG_SLIT_DELIM_CAPTURE— если этот флаг указан, выражение, заключенное в круглые скобки в разделяющем шаблоне, также извлекается из заданной строки и возвращается функцией;PREG_SLIT_OFFSET_CAPTURE— если флаг задан, для каждой найденной подстроки будет указана ее позиция в исходной строке. Этот флаг меняет формат возвращаемых данных: каждое вхождение возвращается в виде массива, в нулевом элементе которого содержится найденная подстрока, а в первом — смещение.-
Пример:
<?php
$user_info="+Иванов+++Москва+++++[email protected]";
$fields = preg_split("/\+{1.}/", $user_info);
for($x=0;$x < sizeof($fields);$x++){
print $fields[$x]. "<br>";
}
?>В окне веб-браузера это будет выглядеть ТАК.
Комментарии(0)
Для добавления комментариев надо войти в систему и авторизоватьсяКомментирование статей доступно только для зарегистрированных пользователей:Зарегистрироваться