Для работы с регулярными выражениями в PHP предусмотрен набор функций, начинающихся с префикса preg, краткое описание которых представлено в таблице 1.
| Функция | Описание |
|---|---|
| preg_grep() | Принимает в качестве одного из параметров массив и возвращает новый массив с элементами, соответствующими или не соответствующими регулярному выражению |
| preg_match() | Выполняет проверку на соответствие регулярному выражению |
| preg_match_all() | Ищет все соответствия регулярному выражению в строке |
| preg_quote() | Экранирует метасимволы регулярных выражений |
| preg_replace() | Осуществляет замену по регулярному выражению |
| preg_replace_callback() | Выполняет поиск по регулярному выражению и замену с использованием функции обратного вызова |
| preg_split() | Разбивает строку по регулярному выражению |
Рассмотрим синтаксис каждой функции из таблицы 1 более подробно.
Функция preg_grep()
Функция preg_grep() принимает в качестве одного из параметров массив и возвращает новый массив с элементами, соответствующими или не соответствующими регулярному выражению. Функция имеет следующий синтаксис:
array preg_grep ( string $pattern , array $input [, int $flags = 0 ] )
Функция принимает в качестве параметра массив $input и возвращает массив тех его элементов, которые соответствуют регулярному выражению $pattern. Если необязательный параметр $flags принимает значение PREG_GREP_INVERT, функция возвращает массив элементов, не соответствующих регулярному выражению $pattern.
Пример preg_grep()
<?php
// возвращает все элементы массива,
// содержащие числа с плавающей точкой
$fl_array = preg_grep ("/^(\d+)?\.\d+$/", $array);
?>
Функция preg_match()
Функция preg_match() осуществляет поиск в строке по регулярному выражению и имеет следующий синтаксис:
int preg_match (string $pattern, string $subject
[, array $matches[, int $flags[, int $offset]]])
В строке $subject ищется соответствие регулярному выражению $pattern.
Если задан необязательный параметр $matches, то результаты поиска помещаются в массив. Элемент $matches[0] будет содержать часть строки, соответствующую вхождению всего шаблона; $matches[1] – часть строки, соответствующую первым круглым скобкам; $matches[2] – вторым и т.д.
Необязательный флаг $flags может принимать единственное значение PREG_OFFSET_CAPTURE, при указании которого изменяется формат возвращаемого массива $matches: каждое вхождение возвращается в виде массива, в нулевом элементе которого содержится найденная подстрока, а в первом – смещение.
Поиск осуществляется слева направо, с начала строки. Дополнительный параметр $offset может быть использован для указания альтернативной начальной позиции для поиска.
Функция preg_match() возвращает количество найденных соответствий. Это может быть 0 (совпадения не найдены) и 1, поскольку preg_match() прекращает свою работу после первого найденного совпадения.
Пример - Получение имени домена из URL
<?php
// получить имя хоста из URL
preg_match("#^(http://)?([^/]+)#i",
"http://www.php.net/index.html", $matches);
$host = $matches[2];
// получить два последних сегмента имени хоста
preg_match("/[^.]+\.[^.]+$/",$host,$matches);
echo "domain name is: ".$matches[0]."\n";
?>
Этот пример выведет:
domain name is: php.net
Функция preg_match_all()
Если необходимо найти либо сосчитать все совпадения, следует воспользоваться функцией preg_match_all(), которая имеет следующий синтаксис:
int preg_match_all ( string $pattern , string $subject ,
array $matches [, int $flags [, int $offset ]] )
Функция ищет в строке $subject все совпадения с регулярным выражением $pattern и помещает результат в массив $matches в порядке, определяемом комбинацией флагов $flags. Так же как и в случае функции preg_match(), можно задать смещение $offset, начиная с которого будет осуществляться поиск в строке $subject.
После нахождения первого соответствия дальнейший поиск будет осуществляться не с начала строки, а от конца последнего найденного вхождения.
Дополнительный параметр $flags может комбинировать следующие значения:
- 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 – если этот флаг установлен, для каждой найденной подстроки будет указана ее позиция в исходной строке. Необходимо помнить, что этот флаг меняет формат возвращаемых данных: каждое вхождение возвращается в виде массива, в нулевом элементе которого содержится найденная подстрока, а в первом – смещение.
Функция preg_match_all() возвращает количество найденных вхождений шаблона (может быть нулем) или false, если во время выполнения возникли какие-либо ошибки.
Функция preg_quote()
Функция preg_quote() экранирует в строке метасимволы регулярных выражений и имеет следующий синтаксис:
string preg_quote ( string $str [, string $delimiter = NULL ] )
Функция принимает параметр $str и добавляет обратный слэш перед каждым метасимволом. Это бывает полезно, если шаблон формируется динамически, например, с участием строки, введенной пользователем.
Символ, указанный в необязательном параметре $delimiter, также подвергается экранированию (в этот параметр часто помещают символ границы регулярного выражения).
Пример
<?php
$keywords = ' for a g3/400';
$keywords = preg_quote($keywords, '/');
echo $keywords; // вернет $40 for a g3\/400
?>
Функция preg_replace()
Функция preg_replace() осуществляет поиск и замену по регулярному выражению и имеет следующий синтаксис:
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject
[, int $limit = -1 [, int $count ]] )
Эта функция ищет в строке $subject соответствие регулярному выражению $pattern и заменяет его на $replacement. Необязательный параметр $limit задает количество соответствий, которые необходимо заменить. Если этот параметр не указан или равен -1, то заменяются все найденные соответствия. Параметр $count хранит количество произведенных замен.
Параметр $replacement может содержать ссылки вида \\n; каждая такая ссылка будет заменена на подстроку, соответствующую n-м круглым скобкам. n может принимать значения от 0 до 99, причем ссылка \\0 соответствует вхождению всего шаблона. Выражения в круглых скобках нумеруются слева направо, начиная с единицы.
Если во время выполнения функции были обнаружены совпадения с шаблоном, будет возвращено измененное значение $subject, в противном случае будет возвращен исходный текст $subject.
Первые три параметра функции preg_replace() могут быть одномерными массивами. В случае если массив использует ключи, при обработке массива они будут взяты в том порядке, в котором расположены в массиве.
В случае если параметры $pattern и $replacement являются массивами, функция preg_replace() поочередно извлекает из обоих массивов по паре элементов и использует их для операции поиска и замены. Если массив $replacement содержит больше элементов, чем $pattern, вместо недостающих элементов для замены будут взяты пустые строки. Если $pattern является массивом, а $replacement – строкой, по каждому элементу массива $pattern будет осуществлен поиск и замена на $replacement (шаблоном будут поочередно все элементы массива, в то время как строка замены остается фиксированной). Вариант, когда $pattern является строкой, а $replacement – массивом, не имеет смысла.
Пример
<?php
$count = 0;
echo preg_replace(array('/\d/', '/\s/'), '*', 'xp 4 to', -1 , $count);
echo $count; //3
?>
Этот пример выведет
xp***to
3
Функция preg_replace_callback()
Функция preg_replace_callback() осуществляет поиск по регулярному выражению и замену с использованием функции обратного вызова и имеет следующий синтаксис:
mixed preg_replace_callback ( mixed $pattern , callback $callback ,
mixed $subject [, int $limit = -1 [, int $count ]] )
Поведение этой функции во многом сходно с preg_replace(), за исключением того, что вместо параметра $replacement необходимо указывать функцию $callback, которой в качестве входящего параметра передается массив найденных вхождений. Функция обратного вызова $callback возвращает строку, в которой будет произведена замена.
Пример - Замена IP адреса на имя хоста в логах сервера
Пусть массив $logent[] хранит записи о заходах пользователей и роботов на ваш сайт. Пример показывает как зафиксированный IP заменить на имя хоста используя функцию preg_replace_callback()
<?php
function resolve_logs($arr) {
return gethostbyaddr($arr[0]);
}
$logent[]='66.249.65.124 - - [28/Jan/2010:06:22:21 +0300]';
$logent[]='64.246.165.50 - - [28/Jan/2010:22:13:53 +0300]';
$logent[]='87.250.254.243 - - [28/Jan/2010:22:20:44 +0300]';
$ipaddr = '/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/';
$logent = preg_replace_callback($ipaddr, resolve_logs, $logent);
foreach($logent as $value)
{
echo $value."<br />";
}
?>
Этот пример вернет
crawl-66-249-65-124.googlebot.com - - [28/Jan/2010:06:22:21 +0300]
www.whois.sc - - [28/Jan/2010:22:13:53 +0300]
spider75.yandex.ru - - [28/Jan/2010:22:20:44 +0300]
Функция preg_split()
Последней функцией из группы Perl-совместимых регулярных выражений является функция preg_split(), которая разбивает строку по регулярному выражению и имеет следующий синтаксис:
array preg_split ( string $pattern , string $subject
[, int $limit = -1 [, int $flags = 0 ]] )
Функция возвращает массив, состоящий из подстрок заданной строки $subject, которая разбита по границам, соответствующим шаблону $pattern.
В случае если параметр $limit указан, функция возвращает не более, чем $limit подстрок, при его отсутствии или равенстве -1 функция действует без ограничений. Последний параметр $flags может быть произвольной комбинацией следующих флагов (соединение происходит при помощи оператора '|'):
- PREG_SPLIT_NO_EMPTY – если этот флаг установлен, функция preg_split() вернет только непустые подстроки;
- PREG_SPLIT_DELIM_CAPTURE – если этот флаг установлен, выражение, заключенное в круглые скобки в разделяющем шаблоне, также извлекается из заданной строки и возвращается функцией;
- PREG_SPLIT_OFFSET_CAPTURE – если этот флаг установлен, для каждой найденной подстроки будет указана ее позиция в исходной строке. Этот флаг меняет формат возвращаемых данных: каждое вхождение возвращается в виде массива, в нулевом элементе которого содержится найденная подстрока, а в первом – смещение.
Пример - получение части строки поиска
<?php
// разделить фразу по любому количеству запятых или пробельных символов,
// куда входят " ", \r, \t, \n и \f
$keywords = preg_split("/[\s,]+/", "hypertext language, programming");
?>