Стандарт регулярных выражений POSIX, возможно, является наиболее простой формой регулярных выражений, доступных программисту РНР. Именно поэтому он представляет собой отличное учебное пособие, поскольку набор функций, реализованный в нем, не включает никаких "усовершенствованных" средств.
В дополнение к стандартным правилам, которые мы уже обсудили, стандарт регулярных выражений POSIX определяет концепцию класса символов как способа еще большего упрощения определения диапазонов символов. Классы символов всегда ограничены с двух сторон двоеточиями и должны быть включены в квадратные скобки.
Существует 12 классов символов:
• alpha — представляет собой букву алфавита (как в верхнем, так и в нижнем ре-
гистре). Это эквивалентно [A-Za-z].
• digit — представляет цифры между 0 и 9 (эквивалент [0-9]).
• alnum —представляет буквы и цифры подобно [0-9A-Za-z].
• blank — представляет "пробельные" символы — обычно это пробел и знак табу-
ляции.
• cntrl — представляет 'управляющие" символы, такие как DEL, INS и тому по-
добные.
• graph — представляет все печатные символы за исключением пробелов.
• lower — представляет только буквы нижнего регистра.
• upper — представляет только буквы верхнего регистра.
• print — представляет все печатные символы.
• punct — представляет знаки пунктуации, такие как . или ,.
• space — пробел.
• xdigit — представляет шестнадцатеричные цифры.
Это позволяет, например, переписать наше выражение проверки электронного
адреса следующим образом:
[[:alnum:]_]+@[[:alnum:]J+\. [[:alnum:]_] {2,4}
Такая нотация намного проще и, очевидно, снижает вероятность ошибок.
Другая важная концепция, реализованная в расширении POSIX — это ссылка. Ранее в настоящей главе уже было показано, как скобки используются для группирования регулярных выражений. Когда вы используете их в регулярных выражениях POSIX, то при интерпретации выражения интерпретатор присваивает числовой идентификатор каждому из сгруппированных выражений, для которых найдены совпадения. Этот идентификатор может использоваться позднее в разных операциях, таких как поиск и замена.
Например, рассмотрим следующую строку и регулярное выражение:
marcot@tabi.ni. са
([ [ .-alpha: ] ] +) @ ([ [: alpha: ]]+) \. ( [ [ :alpha: ] ] {2, 4 })
Регулярное выражение должно соответствовать предшествующему электронному адресу. Однако, поскольку мы группируем имя пользователя, доменное имя и расширение доменного имени становятся ссылкой, как показано в табл. 3.1.
Таблица 3.1. Ссылки в регулярных выражениях
Номер Значение
ссылки
0 marcot@tabini. са (строка соответствующая полному регулярному выражению).
1 marcot
2 tabini
3 са
PHP обеспечивает поддержку POSIX с помощью функций класса ereg*. Простейшая форма соответствия регулярному выражению определяется с помощью функции
ereg ():
ereg (pattern, string[, matches)
Функция ereg () работает, компилируя регулярное выражение, переданное в параметре pattern, и затем сравнивая его со string. Если регулярное выражение соответствует string, функция возвращает значение true, в противном случае — false. Если указан параметр matches, он заполняется массивом, содержащим все ссылки, заданные pattern, которые были найдены в s t r i n g (см. листинг 3.1).
Листинг 3.1. Заполнение шаблонов с помощью ereg
$s = 'marcot@tabini.ca'; i f (ereg (' ( [ [ : a l p h a : ] ] + ) @ ( [ [ : a l p h a : ] ] + ) \ . ( [ [ : a l p h a : ] ] { 2 , 4 } ) ' , $s, $matches)) { echo "Регулярное выражение успешно. Совпадение сохранено\п"; var_dump ($matches); } else { echo "Регулярное выражение не успешно.\n";
Если выполнить приведенный выше сценарий, результат будет следующим: Регулярное выражение успешно. Совпадение сохранено
аггау(4) { [0]=> string(16) "marcot@tabini.ca" [1]=> string(6) "marcot" [ 2 ] = > • string(6) "tabini" [3]=> string(2) "са" }
Это означает, что было найдено совпадение регулярному выражению строки, хранимой в переменной $s, и найденные ссылки возвращены в массиве $matches. Если вас не интересует соответствие, чувствительное к регистру (и вы не хотите специфицировать все символы дважды при создании регулярного выражения), можете использовать функцию eregi (). Она принимает те же параметры и ведет себя таким же образом, что и ereg (), с тем отличием, что регистр букв игнорируется при поиске совпадения строки с регулярным выражением (см. листинг 3.2).
Листинг 3.2. Совпадение с шаблоном, нечувствительное к регистру $а = "UPPERCASE"; echo (int) ereg ('uppercase', $a) ; echo "\n"; echo (int) eregi ('uppercase', $a) ; echo "\n"; ?>
В первом случае совпадение не будет найдено, потому что ereg () выполняет проверку на предмет совпадения, чувствительного к регистру, со строкой $а. Второй вызов найдет соответствие строки регулярному выражению, поскольку функция eregi () выполняет проверку соответствия по алгоритму, не зависящему от регистра.
Ссылки делают регулярные выражения даже еще более эффективным инструментом для осуществления операция поиска и замены. Для этой цели РНР предлагает функцию ereg_replace () и ее нечувствительный к регистру вариант eregi_replace (): ereg_replace (pattern, replacement, string);
Функция ereg_replace() сначала сравнивает регулярное выражение pattern со строкой string. Затем она использует ссылки, созданные регулярным выражением, в replacement и возвращает результирующую строку. В листинге 3.3 показан пример.
Листинг 3.3. Использование функции ereg_replace ()
<?php
$s = 'marcot@tabini.ca';
echo ereg_replace ('([[:alpha:]]+)@([[:alpha:]]+)\.([[:alpha:]]{2,4})',
'\1 at \2 dot \ 3 \ Ss)
После выполнения сценарий выводит следующую строку:
marcot at tabini' dot ca
Как видите, компилятор регулярных выражений из 5s извлекает три ссылки, которые используются для подстановки соответствующих фрагментов заменяющей строки.
|