Возможности эффективной организации, поиска и распространения информации
давно представляли интерес для специалистов в области компьютерных технологий.
Поскольку информация в основном представляет собой текст, состоящий из
алфавитно-цифровых символов, разработка средств поиска и обработки информации по
шаблонам, описывающим текст, стала предметом серьезных теоретических
исследований.
Поиск по шаблону позволяет не только находить определенные фрагменты текста,
но и заменять их другими фрагментами. Одним из стандартных примеров поиска по
шаблону являются команды поиска/замены в текстовых редакторах - например, в MS
Word, Emacs и в моем любимом редакторе vi. Всем пользователям UNIX хорошо
известны такие программы, как sed, awk и grep; богатство возможностей этих
программ в значительной степени обусловлено средствами поиска по шаблону.
Механизмы поиска по шаблону решают четыре основные задачи:
поиск строк, в точности совпадающих с заданным шаблоном;
поиск фрагментов строк, совпадающих с заданным шаблоном;
замену строк и подстрок по шаблону;
поиск строк, с которыми заданный шаблон не совпадает.
Появление Web породило необходимость в более быстрых и эффективных средствах
поиска данных, которые бы позволяли пользователям со всего мира находить нужную
информацию среди миллиардов web-страниц. Поисковые системы, онлайновые
финансовые службы и сайты электронной коммерции - все это стало бы абсолютно
бесполезным без средств анализа гигантских объемов данных в этих секторах.
Действительно, средства обработки строковой информации являются жизненно важной
составляющей практически любого сектора, так или иначе связанного с современными
информационными технологиями. В этой главе основное внимание посвящено средствам
обработки строк в РНР. Мы рассмотрим некоторые стандартные строковые функции (в
языке их больше 60!), а из приведенных определений и примеров вы получите
сведения, необходимые для создания web-приложений. Но прежде чем переходить к
специфике РНР, я хочу познакомить вас с базовым механизмом, благодаря которому
становится возможным поиск по шаблону. Речь идет о регулярных выражениях.
Регулярные выражения
Регулярные выражения лежат в основе всех современных технологий поиска по
шаблону. Регулярное выражение представляет собой последовательность простых и
служебных символов, описывающих искомый текст. Иногда регулярные выражения
бывают простыми и понятными (например, слово dog), но часто в них присутствуют
служебные символы, обладающие особым смыслом в синтаксисе регулярных выражений,
- например, <(?)>.*</.?>.
В РНР существуют два семейства функций, каждое из которых относится к
определенному типу регулярных выражений: в стиле POSIX или в стиле Perl. Каждый
тип регулярных выражений обладает собственным синтаксисом и рассматривается в
соответствующей части главы. На эту тему были написаны многочисленные учебники,
которые можно найти как в Web, так и в книжных магазинах. Поэтому я приведу лишь
основные сведения о каждом типе, а дальнейшую информацию при желании вы сможете
найти самостоятельно. Если вы еще не знакомы с принципами работы регулярных
выражений, обязательно прочитайте краткий вводный курс, занимающий всю
оставшуюся часть этого раздела. А если вы хорошо разбираетесь в этой области,
смело переходите к следующему разделу.
Синтаксис регулярных выражений (POSIX)
Структура регулярных выражений POSIX чем-то напоминает структуру типичных
математических выражений - различные элементы (операторы) объединяются друг с
другом и образуют более сложные выражения. Однако именно смысл объединения
элементов делает регулярные выражения таким мощным и выразительным средством.
Возможности не ограничиваются поиском литерального текста (например, конкретного
слова или числа); вы можете провести поиск строк с разной семантикой, но похожим
синтаксисом - например, всех тегов HTML в файле.
Простейшее регулярное выражение совпадает с одним литеральным символом -
например, выражение g совпадает в таких строках, как g, haggle и bag. Выражение,
полученное при объединении нескольких литеральных символов, совпадает по тем же
правилам - например, последовательность gan совпадает в любой строке, содержащей
эти символы (например, gang, organize или Reagan).
Оператор | (вертикальная черта) проверяет совпадение одной из нескольких
альтернатив. Например, регулярное выражение php | zend проверяет строку на
наличие php или zend.
Квадратные скобки
Квадратные скобки ([ ]) имеют особый смысл в контексте регулярных выражений -
они означают <любой символ из перечисленных в скобках>. В отличие от
регулярного выражения php, которое совпадает во всех строках, содержащих
литеральный текст php, выражение [php] совпадает в любой строке, содержащей
символы р или h. Квадратные скобки играют важную роль при работе с регулярными
выражениями, поскольку в процессе поиска часто возникает задача поиска символов
из заданного интервала. Ниже перечислены некоторые часто используемые интервалы:
[0-9] - совпадает с любой десятичной цифрой от 0 до 9;
[a-z] - совпадает с любым символом нижнего регистра от а до z;
[A-Z] - совпадает с любым символом верхнего регистра от А до Z;
[a -Z] - совпадает с любым символом нижнего или верхнего регистра от а до
Z.
Конечно, перечисленные выше интервалы всего лишь демонстрируют общий принцип.
Например, вы можете воспользоваться интервалом [0-3] для обозначения любой
десятичной цифры от 0 до 3 или интервалом [b-v] для обозначения любого символа
нижнего регистра от b до v. Короче говоря, интервалы определяются совершенно
произвольно.
Квантификаторы
Существует особый класс служебных символов, обозначающих количество
повторений отдельного символа или конструкции, заключенной в квадратные скобки.
Эти служебные символы (+, * и {...}) называются квантификаторами. Принцип их
действия проще всего пояснить на примерах:
р+ означает один или несколько символов р, стоящих подряд;
р* означает ноль и более символов р, стоящих подряд;
р? означает ноль или один символ р;
р{2} означает два символа р, стоящих подряд;
р{2,3} означает от двух до трех символов р, стоящих подряд;
р{2,} означает два и более символов р, стоящих подряд.
Прочие служебные символы
Служебные символы $ и ^ совпадают не с символами, а с определенными позициями
в строке. Например, выражение р$ означает строку, которая завершается символом
р, а выражение ^р - строку, начинающуюся с символа р.
Конструкция [^a-zA-Z] совпадает с любым символом, не входящим в указаные
интервалы (a-z и A-Z).
Служебный символ . (точка) означает <любой символ>. Например,
выражение р.р совпадает с символом р, за которым следует произвольный символ,
после чего опять следует символ р.
Объединение служебных символов приводит к появлению более сложных выражений.
Рассмотрим несколько примеров:
^.{2}$ - любая строка, содержащая ровно два символа;
<b>(.*)</b> - произвольная последовательность символов,
заключенная между <Ь> и </Ь> (вероятно, тегами HTML для вывода
жирного текста);
p(hp)* - символ р, за которым следует ноль и более экземпляров
последовательности hp (например, phphphp).
Иногда требуется найти служебные символы в строках вместо того, чтобы
использовать их в описанном специальном контексте. Для этого служебные символы
экранируются обратной косой чертой (). Например, для поиска денежной суммы в
долларах можно воспользоваться выражением $[0-9]+, то есть <знак доллара, за
которым следует одна или несколько десятичных цифр>. Обратите внимание на
обратную косую черту перед $. Возможными совпадениями для этого регулярного
выражения являются $42, $560 и $3.
Для удобства программирования в стандарте POSIX были определены некоторые
стандартные интервальные выражения, также называемые символьными классами
(character classes). Символьный класс определяет один символ из заданного
интервала - например, букву алфавита или цифру:
[[:alpha:]] - алфавитный символ (aA-zZ);
[[:digit:]]-цифра (0-9);
[[:alnum:]] - алфавитный символ (aA-zZ) или цифра (0-9);
[[:space:]] - пропуски (символы новой строки, табуляции и т. д.).
Функции РНР для работы с регулярными выражениями (POSIX-совместимые)
В настоящее время РНР поддерживает семь функций поиска с использованием
регулярных выражений в стиле POSIX:
еrеg( );
еrеg_rерlасе( );
eregi( );
eregi_replace( );
split( );
spliti( );
sql_regcase( ).
Описания этих функций приведены в следующих разделах.
ereg( )
Функция еrеg( ) ищет в заданной строке совпадение для шаблона. Если
совпадение найдено, возвращается TRUE, в противном случае возвращается FALSE.
Синтаксис функции ereg( ):
int ereg (string шаблон, string строка [, array совпадения])
Поиск производится с учетом регистра алфавитных символов. Пример
использования ereg( ) для поиска в строках доменов .соm:
$is_com -
ereg("(.)(com$)", $email): // Функция возвращает TRUE, если $email
завершается символами ".com" // В частности, поиск будет успешным для строк
// "www.wjgilmore.com" и "someemail@apress.com"
Обратите внимание: из-за присутствия служебного символа $ регулярное
выражение совпадает только в том случае, если строка завершается символами .com.
Например, оно совпадет в строке "www.apress.com", но не совпадет в строке
"www.apress.com/catalog".
Необязательный параметр совпадения содержит массив совпадений для всех
подвыражений, заключенных в регулярном выражении в круглые скобки. В листинге
показано, как при помощи этого массива разделить URL на несколько сегментов.
Вывод элементов массива $regs
$url = "http://www.apress.com"; //
Разделить $url на три компонента: "http://www". "apress" и "com" $www_url =
ereg("^(http://www).([[:alnum:]+.([[:alnum:]]+)". $url, $regs); if
($www_url) : // Если переменная $www_url содержит URL echo $regs[0]; // Вся
строка "http://www.apress.com" print "<br>"; echo $regs[l]; //
"http://www" print "<br>"; echo $regs[2]; // "apress" print
"<br>"; echo $regs[3]; // "com" endif;
При выполнении сценария будет получен следующий результат:
http://www.apress.com http://www apress com
ereg_replace( )
Функция ereg_replace( ) ищет в заданной строке совпадение для шаблона и
заменяет его новым фрагментом. Синтаксис функции ereg_replace( ):
Функция ereg_replace( ) работает по тому же принципу, что и ereg( ), но ее
возможности расширены от простого поиска до поиска с заменой. После выполнения
замены функция возвращает модифицированную строку. Если совпадения
отсутствуют, строка остается в прежнем состоянии. Функция ereg_replace( ),
как и еrеg( ), учитывает регистр символов. Ниже приведен простой пример,
демонстрирующий применение этой функции:
У средств поиска с заменой в языке РНР имеется одна интересная возможность -
возможность использования обратных ссылок на части основного выражения,
заключенные в круглые скобки. Обратные ссылки похожи на элементы необязательного
параметра-массива совпадения функции еrеg( ) за одним исключением: обратные
ссылки записываются в виде
Библиотека GTK+ прошла долгий путь развития и сейчас очень популярна. GNOME, одна из ведущих оконных сред, использует GTK+ почти исключительно, GIMP построен на GTK+, множество коммерческих разработчиков ПО, таких как Abobe, NVidia и VMware, решили использовать эту библиотеку в качестве графической основы для своих продуктов... подробнее
Slashdot.org – популярный новостной портал с посещаемостью 50 млн. человек в месяц. Авторы проекта добились такого успеха, предоставляя пользователям свежие и интересные новости из мира IT... подробнее
Здесь рассматривается вопрос, что бывает, если запустить некий скрипт почти одновременно (что происходит, например, при большой нагруженности сервера) несколько раз, т.е. запустить несколько копий одного и того же скрипта. И к чему это может привести... подробнее
...и снова о спаме. Кто о нем только не писал, и все писали, что это плохо и ай-яй-яй. Я не буду оригинальничать, и тоже скажу – это плохо. Это ай-яй-яй. Как бороться со спамерами со своей стороны... подробнее