Регулярные выражения — это специализированный язык поиска и осуществление манипуляций с подстроками в тексте. Синтаксис регулярных выражений является достаточно сложным и его изучение требует серьезных усилий.
Базовый синтаксис и создание регулярных выражений
В настоящий момент существует несколько диалектов регулярных выражений. В данный момент будет рассмотрен синтаксис 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)
Для добавления комментариев надо войти в систему и авторизоватьсяКомментирование статей доступно только для зарегистрированных пользователей:Зарегистрироваться