|
Регулярные выражения 2Источник: http://webhowto.ru/ Авторство: Neoweb Рассмотрим функции для работы с регулярными выражениями
формата PCRE. <? $c=preg_match("/\w\d{2}/","k22 007 T34 bx z13", $arr); echo $c; ?> Возвращает 1. Третий параметр можно было и не указывать. Массив $arr, будет состоять всего из одного элемента. $arr[0]="k22". Возникает естественный вопрос: зачем возвращать совпадение в виде массива, если он (массив) будет всегда состоять только из одного элемента? Оказывается это не так. Вспомните первую часть этой статьи. Там я рассказывал про такой спецсимвол, как круглые скобки. Если в регулярном выражении встречаются круглые скобки, то парсер рассматривает их содержимое, как отдельное выражение. Естественно, что этих скобок может встречаться любое необходимое количество. Для этого preg_match и создает массив, чтобы вернуть результат поиска по всем регулярным выражениям. Рассмотрим всё на примере: <?php $strin="nex z1c dyt b2k kid d1l d1l d1l"; preg_match("/\w(\d)(\w)/",$strin,$arr); print_r($arr); ?> Возможно функция bool print_r (mixed expression) является для Вас новой (я о ней ещё не рассказывал). Используется она довольно редко, но в данном случае удобна. Тип параметра, который может быть передан функции: строка, любое число, массив, объект. Для числа и строки, она не делает ничего интересного, просто выводит их, как echo или print. Если же передать ей массив (особенно актуально для многомерного массива), то он будет отображен в удобном виде (наглядно). Вернёмся к нашему примеру. Выражение будет соответствовать любой строке, которая состоит из 3 символов (два любых символа и цифра между ними). Массив $arr выглядит так: Array ([0] => z1c [1] => 1 [2] => c ). Нулевой элемент - часть строки, которая соответствует полному регулярному выражению, а последующие - его фрагментам, т.е. частям выражения, заключенным в круглые скобки. int preg_match_all ( string pattern, string subject, array matches [, int flags]) - делает, то же самое, что и предыдущая функция, только поиск ведет не до первого совпадения, а глобально. Пускай нужно выделить из текста все числа типа float: <? $strin="pi=3.14 g=9.8 r=7.31 "; preg_match_all("/(\d+)\.(\d+)/",$strin,$arr); print_r($arr); ?> Результат: Array ( [0] => Array ( [0] => 3.14 [1] => 9.8 [2] => 7.31 ) [1] => Array ( [0] => 3 [1] => 9 [2] => 7 ) [2] => Array ( [0] => 14 [1] => 8 [2] => 31 ) ). Результатом работы функции является массив, каждый элемент которого, в свою очередь, тоже имеет тип массива. Первый "подмассив" состоит из частей строки, которые соответствуют всему регулярному выражению. Второй содержит элементы, соответствующие целым частям чисел, а третий - вещественным. Такой порядок можно и изменить, указав третий параметр int flags. Он может принимать следующие значения: PREG_PATTERN_ORDER -(используется по умолчанию) если поиск производится таким образом, то дело обстоит так же, как в предыдущем примере. Нулевой элемент array matches является массивом, в котором находятся подстроки с полным соответствием, первый - массив с соответствием по первой части выражения и т.д. PREG_SET_ORDER : <? $strin="pi=3.14 g=9.8 r=7.31 "; preg_match_all("/(\d+)\.(\d+)/", $strin,$arr, PREG_SET_ORDER); print_r($arr); ?> Результат: Array ( [0] => Array ( [0] => 3.14 [1] => 3 [2] => 14 ) [1] => Array ( [0] => 9.8 [1] => 9 [2] => 8 ) [2] => Array ( [0] => 7.31 [1] => 7 [2] => 31 ) ) Результаты поиска заносятся в массив array matches по месту их нахождения в тексте. Пусть, дана строка, в которой некоторые слова выделены каким - либо парным тэгом. $str="I love <i>PHP</i>. It is <b>cool</b>"; Наша задача - получить выделенную подстроку, и узнать, каким тэгом она обрамлена. Регулярное выражение не может выглядеть так: ~<(\w+)>(.*)</(\w)>~, т.к. оно будет соответствовать и <i>PHP</b> и <pre>PHP</i> и т.д. Нам же нужно соответствие, только если тэги парные. Выход из ситуации:
<?php $str="I love <i>PHP</i>. It is <b>cool</b>"; preg_match_all( "~<(\w+)>(.*)</\\1>~",$str,$arr); print_r($arr); echo "Слово ".$arr[2][0]." выделено тэгом ".$arr[1][0]; echo "<br>Слово ".$arr[2][1]." выделено тэгом ".$arr[1][1]; ?> Результат: Array ( [0] => Array ( [0] => PHP [1] => cool ) [1] => Array ( [0] => i [1] => b ) [2] => Array ( [0] => PHP [1] => cool ) ) Слово PHP выделено тэгом i Слово cool выделено тэгом b Позже мы ещё поговорим о карманах. mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]) - функция производит поиск с заменой по регулярному выражению. Одна из самых интересных и часто используемых функций. Поиск производится в тексте subject по регулярному выражению pattern. Каждое соответствие заменяется текстом, заданным в replacement. Если совпадения были найдены, функция возвращает текст с заменами, в противном случае - текст без изменений. Если необходимо произвести замены сразу по нескольким регулярным выражениям, то в качестве параметров pattern и replacement могут быть переданы массивы. Совпадение по первому регулярному выражению из массива pattern будет изменено первой строкой массива replacement, второе выражение - второй строкой и т.д. Однако так будет, только если элементы этих массивов добавлялись в них по очереди (нулевой элемент, первый и т.д.). В общем случае замена происходит по порядку добавления в массив. Пример: <?php $subject="C, Java и Perl"; $pattern[0]="/C/"; $pattern[1]="/Java/"; $pattern[2]="/Perl/"; $replacement[2]="TCL"; $replacement[1]="PHP"; $replacement[0]="Ocaml"; echo preg_replace($pattern,$replacement,$subject); ?> Результат: TCL, PHP и Ocaml. Хотя, казалось бы, нужно было ожидать: Ocaml, PHP и TCL. Если для Вас важно, чтобы замена проходила в соответствии с ключами массива, то предварительно примените функцию ksort(), которая отсортирует массивы $pattern и $replacement по ключу. Вот ещё один стандартный пример, который конвертирует дату из формата дд/мм/гггг в формат дд.мм.гггг. <?php $text = 'Сегодня 27/06/2003'; $text = preg_replace("/(\d{2})\/(\d{2})\/(\{4})/", "\\2.\\1.\\3",$text); echo $text; ?> Следующие два примера более интересны и чаще используются: 1)Преобразование e-mail адреса. Ищет в тексте строки вида: usermail@userhost и меняет их на HTML ссылки <a href=" usermail@userhost "> usermail@userhost </a>. <?php $text = 'E-mail Васи - va-sya@mail.ru. И ещё один - pupkin@mail.fbi.gov .'; echo $text; $text=preg_replace("/(([\w-.]+)@(\w+)(\\.[\w-]+)*)/", '<a href="mailto:$0">$0</a>',$text); echo $text; ?> С помощью этого регулярного выражения вы сможете проверить почтовый адрес на правильность (например, при проверке соответствующего поля какой-то формы): <?php if(!preg_match("/([\w-.]+)@(\w+)(\\.[\w-]+)*/")), $email) echo "$email не является адресом электронной почты"; ?> Так же, как только что мы преобразовывали, e-mail адреса, можно поступить и с гиперссылками. Заменим подстроки типа протокол://URL на <a href=" протокол://URL "> протокол://URL </a>. Напоследок, краткий обзор ещё нескольких полезных функций. string preg_quote ( string str [, string delimiter]) - расставляет в строке str символ '\' перед всеми спецсимволами регулярных выражений (. \\ + * ? [ ^ ] $ ( ) { } = ! < > | :), для отмены их действия, и возвращает видоизменённую строку. Если задан необязательный параметр delimiter, то перед этим символом также будет проставлен '\'. Функция полезна для предварительной обработки строки, которая будет использоваться, в регулярном выражении, для поиска совпадений по какому-либо тексту (в случае если она содержит спецсимволы). array preg_grep (string pattern, array input). Ищет совпадения в массиве array input по регулярному выражению string pattern и возвращает массив, состоящий из элементов, в которых совпадения были найдены. Пример: <?php $str=array('this is php(perl) var $p', 'this is some text','$h','@3'); echo $str[0]; $regexp='/\$[A-Za-z_]+/'; $output=preg_grep($regexp,$str); print_r($output); ?> На этом я заканчиваю рассказ о регулярных выражениях. В
статье получилось довольно мало примеров, но к регулярным
выражениям (к их практическому применению) я буду возвращаться
ещё очень часто в следующих статьях. А пока осмыслите
вышесказанное, и потренируйтесь в написании рег. выражений.
Если что-то не получается, пишите мне, всегда буду рад
помочь.
|
Copyright © <LMTH>. Все материалы являются собственностью их авторов.
При перепечатывании ссылка на http://www.magaz.org/ как на источник информации обязательна. Правила использования материалов журнала |