| |
я внешняя пара скобок), во второй — как раз день, в
третий — месяц и, наконец, в четвертый — год.
Обратите еще раз внимание на порядок нумерации карманов — она идет по
номеру открывающейся скобки.
Как уже упоминалось, в нулевой карман в любом случае записывается все найденное
совпадение. В данном примере это будет вся строка.
Как получить содержимое наших карманов? Очень просто: как раз тот список, кото-
рый передается по ссылке функции ereg() третьим параметром, и есть карманы.
Часть IV. Стандартные функции PHP 306
Исходя из этого, имеем следующую программу на PHP, выполняющую требуемые
действия:
$str=" 15-16-2000 "; // к примеру
// Разбиваем строку на куски при помощи ereg
ereg("^ *(([0-9]+)-([0-9]+)-([0-9]+)) *$",$str,$Pockets);
// Теперь разбираемся с карманами
echo "Дата без пробелов: $Pockets[1] "
echo "День: $Pockets[2] ";
echo "Месяц: $Pockets[3] ";
echo "Год: $Pockets[4] ";
Вот теперь мы можем усложнить наш пример, объявив, что числа внутри даты могут
разделяться не только дефисом, но и, скажем, точкой или косой чертой, и, к тому
же,
между цифрами могут также попасться паразитные пробелы. Вот как будет выглядеть
выражение, реализующее разбор таких строк:
^ *([0-9]+) *[-./] *([0-9]+) *[-./] *([0-9]+) *$
Использование карманов в функции замены
Мы рассмотрели только самый простой способ использования карманов — прямой их
просмотр после выполнения поиска. Однако возможности, предоставляемые языком
RegEx, куда шире. Особенно часто эти возможности применяются для замены с по-
мощью регулярных выражений.
Предположим, нам нужно все слова в строке, начинающиеся с "доллара" $, сделать
"жирными", — обрамить тэгами и , — для последующего вывода в браузер.
Это может понадобиться, если мы хотим текст некоторой программы на PHP вывести
так, чтобы в нем выделялись имена переменных. Очевидно, выражение для обнару-
жения имени переменной в строке будет таким: \$[a-zA-Z_][[:alnum:]]*.
Но как нам использовать его в функции ereg_Replace()? Вот фрагмент програм-
мы, которая делает это:
$str=" $a=10; for($i=0; $i<10; $i++) echo $i; ?> // к примеру
$str=ereg_Replace("(\\$[a-zA-Z_][[:alnum:]]*)","\\1",$str);
Пожалуйста, обратите опять внимание на то, что слэши должны удваиваться.
Нетрудно догадаться, как "оно" работает: просто во время замены везде вместо
соче-
тания \1 подставляется содержимое кармана номер 1.
Глава 22. Основы регулярных выражений в формате RegEx 307
Использование карманов
в функции сопоставления
И даже на том, что было описано выше, возможности карманов не исчерпываются.
Мы можем задействовать содержимое карманов и в функции ereg() — раньше, чем
закончится сопоставление. А именно, управлять ходом поиска на основе данных в
карманах.
В качестве примера рассмотрим такую далеко не праздную задачу. Известно, что в
строке есть подстрока, обрамленная какими-то HTML-тэгами (например, или
), но неизвестно, какими. Требуется поместить эту подстроку в карман,
чтобы в
дальнейшем с ней работать. Разумеется, закрывающий тэг должен соответствовать
открывающему — например, к тэгу парный — , а к — .
Задача решается с помощью такого регулярного выражения:
<([[:alnum:]]+)>([^<]*)\1>
При этом результат окажется во втором кармане, а имя тэга — в первом. Вот как
это
работает: PHP пытается найти открывающий тэг, и, как только находит, записывает
его имя в первый карман (так как это имя обрамлено в выражении первой парой
ско-
бок). Дальше он смотрит вперед и, как только наталкивается на , определяет,
сле-
дует ли за ним то самое имя тэга, которое у него лежит в первом кармане. Это
дейст-
вие заставляет его предпринять конструкция \1, которая замещается на содержимое
первого кармана каждый раз, когда до нее доходит очередь. Если имя не совпадает,
то такой вариант PHP отбрасывает и "идет" дальше, а иначе сигнализирует о
совпа-
дении.
Вот фрагмент программы, который все
|
|