Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

web - tec / PHP 5 для начинающи

.pdf
Скачиваний:
69
Добавлен:
12.06.2015
Размер:
26.79 Mб
Скачать

Надежный и понятный код 243

<?php

$words = "Vote twice or more if you can.";

if (ereg("twice if", $words, $reg)) echo "Найдена строка '$reg[0]'"; ?>

Эта строка не будет совпадать с регулярным выражением, потому что в ней нет точного соответствия образцу. Аналогично пробелы внутри образца также имеют значение:

<?php

$words1 = "The bigdog is in the pound..."; $words2 = "{...}but the dog is in the cornfield";

$regexp = " dog";

if (ereg($regexp, $words1, $reg)) echo "Найдена строка '$reg[0]'"; if (ereg($regexp, $words2, $reg)) echo "Найдена строка '$reg[0]'";

?>

Такое регулярное выражение может найти только второе вхождение слова dog, потому что оба вызова ereg() специально ищут пробел, за которым следует три бук+ вы ‘‘d’’, ‘‘o’’ и ‘‘g’’.

Специальные символы

Синтаксис регулярных выражений включает в себя использование специальных символов (которые не следует путать со специальными символами HTML). В регуляр+ ных выражениях специальные символы позволяют создавать более сложные выраже+ ния, в которых целые части образца могут состоять из одного из множества символов или совпадение с образцом должно начинаться с определенной позиции строки.

Как уже отмечалось, чтобы экранировать специальное значение какого+либо сим+ вола, можно использовать обратную косую черту. Например, для вывода на экран символа двойной кавычки необходимо использовать escape+последовательность \" (то же самое делает функция addslashes() при добавлении строк в базу данных).

Ниже показаны символы, имеющие специальное значение в регулярных выраже+ ниях. Для того чтобы использовать их буквально, необходимо предварять их симво+ лами обратной косой черты.

. * ? + [ ] ( ) { } ^ $ | \

Для всех остальных символов автоматически предполагается их буквальное значе+ ние. Например, чтобы в предыдущем примере задать образец ‘‘...’’, необходимо ис+ пользовать следующий код:

<?php

$words1 = "The bigdog is in the pound...";

$regexp = "pound\.\.\.";

if (ereg($regexp, $words1, $reg)) echo "Найдена строка '$reg[0]'"; ?>

Регулярное выражение ‘‘pound…’’ совпадает с частью тестовой строки, кроме это+ го, оно применимо в следующем примере, потому что точка в данном случае интер+ претируется не как точка в регулярном выражении, а как специальный символ, кото+ рый соответствует любому символу:

<?php

$words1 = "The bigdog is in the pound but the dog is in the cornfield.";

$regexp = "pound...";

if (ereg($regexp, $words1, $reg)) echo "Найдена строка '$reg[0]'"; ?>

244 Глава 5

Этот код выдаст следующий результат:

Найдена строка 'pound bu'

Это происходит потому, что точка (.) является специальным символом. Она соот+ ветствует одному любому символу кроме символа новой строки. Поэтому в данном случае три точки совпадают с любыми тремя символами после слова ‘‘pound’’, а не только с тремя точками.

Некоторые распространенные образцы и их варианты

Существует несколько доступных вариантов для создания образцов в регулярных выражениях. Рассмотрим их по порядку.

Классы символов: [xyz]

Образец, заключенный в квадратные скобки, называется классом символов и означа+ ет, что допускается совпадение с любым из этих символов. Например, регулярное вы+ ражение ‘‘w[ao]nder’’ совпадает как со словом ‘‘wander’’, так и со словом ‘‘wonder’’.

Чтобы создать исключающий класс символов, необходимо начать его со знака ^. Например, регулярное выражение ‘‘[^1234567890]’’совпадает с любым символом, кроме цифры.

Чтобы задать диапазон символов, можно использовать дефис. Например, преды+ дущее регулярное выражение можно переписать так: [^0+9], а выражение [a+z] будет соответствовать строчным латинским буквам.

Можно использовать один или несколько диапазонов вместе, поэтому для поиска одной шестнадцатеричной цифры можно использовать выражение [0+9A+F]. Квадрат+ ные скобки содержат целое выражение, но представляют только один+единственный символ, который соответствует любому символу, попадающему в один из диапазонов данного класса. Если бы использовалось выражение [0+9][A+F], то оно соответствова+ ло бы одной цифре, за которой следует одна буква от A до F включительно.

Некоторые классы символов, такие как цифры, буквы и различные типы пустого пространства, встречаются в проверяемых строках снова и снова. Для них использу+ ется несколько лаконичных шаблонов. Ниже представлены наиболее распространен+ ные из таких шаблонов, а также их значения.

Шаблон

Класс символов

Описание

 

 

 

\d

[0-9]

Цифры от 0 до 9

\w

[0-9A-Za-z_]

Символ “слово” (алфавитно-цифровые символы)

\s

[ \t\n\r]

Пробельные символы (пробел, символ табуляции, новой

 

 

строки или возврата каретки)

В следующей таблице приведены исключающие формы указанных шаблонов:

Шаблон

Класс символов

Описание

 

 

 

\D

[^0-9]

Любой нецифровой символ

\W

[^0-9A-Za-z_]

Любой символ кроме символа “слово”

\S

[^\t\n\r]

Любой символ кроме пробельного

 

 

 

Надежный и понятный код 245

Якоря

Классы символов совпадают с символами в любом месте строки, однако опреде+ ленные символы можно использовать для того, чтобы указать, где в строке должно встретиться совпадение. Такие символы называются якорями (anchors).

Имеется два якоря: якорь ^ используется в начале образца и привязывает выраже+ ние к началу строки, а якорь $ используется в конце образца и привязывает его к кон+ цу строки. Чтобы проверить, заканчивается ли строка точкой (не забудьте, что точка может быть специальным символом), можно использовать регулярное выражение \.$. Аналогично, чтобы проверить, присутствует ли в начале строки прописная буква ‘‘B’’, можно использовать выражение ^B.

Границы слова

Поиск слов, перед которыми или после которых есть знаки пунктуации, можно об+ легчить с помощью специальных символов ++++++ границ слова (word boundaries). Символы границ слова позволяют задать образец как совпадение с началом или концом слова. Такие символы необходимы, поскольку слова не всегда отделяются друг от друга пробе+ лами ++++++ иногда слова разделяются запятыми, точками и другими знаками пунктуации.

Например, чтобы искать однобуквенные слова, можно использовать границу слова \b, такое регулярное выражение будет иметь вид \b\w\b. Как и якоря, шаблон \b, по су+ ти, совпадает не с каким+либо отдельным символом, а с позицией между чем+то, не яв+ ляющимся символом слова (\W или конец строки), и символом слова (отсюда и назва+ ние ++++++ граница слова).

Альтернативы

В некоторых случаях может оказаться полезным символ, создающий исключающее условие (или/или). В регулярных выражениях оператор ‘‘исключающего или’’ такой же, как битовый оператор ‘‘или’’: |. Например, чтобы найти строку ‘‘yes’’ или ‘‘maybe’’, следует использовать выражение yes|maybe.

Квалификаторы

Квалификаторы (qualifiers) ++++++ символы ?, + и * ++++++ позволяют создавать регулярные выражения, совпадающие с набором символов, который может встречаться только один раз, несколько раз или не встречаться вообще. Простейшим из них является знак вопроса ?, соответствующий предыдущему символу (символам) или метасимволу (метасимволам), который встречается только однажды или ни разу. Например, чтобы найти слово ‘‘he’’ или ‘‘she’’, можно использовать выражение s?he (буквы ‘‘s’’ и ‘‘h’’ отделены друг от друга знаком вопроса). Такое выражение ищет любую из двух букв. Если в строке нет буквы ‘‘s’’, но есть буква ‘‘h’’ (как в слове ‘‘he’’), то такая строка все равно совпадает с данным регулярным выражением.

Чтобы сделать последовательность символов (или метасимволов) необязательной, их можно сгруппировать в скобках: с помощью регулярного выражения (wo)?man можно искать слова ‘‘man’’ или ‘‘woman’’.

Искать одно или несколько вхождений символа (или символов) можно с помощью знака ‘‘плюс’’. Например, для поиска целого слова без указания его длины использует+ ся выражение \w+.

Можно также искать символы, которые могут встречаться любое количество раз или не встречаться вообще (т.е. ни одного, одно или несколько вхождений). Для та+ ких случаев используется квалификатор * (‘‘звездочка’’). Например, чтобы найти прописную букву после любого количества (или ни одного) пробелов в начале строки, используется выражение ^\s*[A-Z].

246 Глава 5

Различия данных квалификаторов наглядно демонстрируются следующими при+ мерами:

hea?t ++++++ находит слова ‘‘heat’’ или ‘‘het’’;

hea+t ++++++ находит ‘‘heat’’, ‘‘heaat’’, ‘‘heaaat’’ и т.д.; hea*t ++++++ находит ‘‘het’’, ‘‘heat’’, ‘‘heaat’’ и т.д.

Начинающие программисты склонны к излишнему использованию комбинаций точки (представляющей любой символ) и звездочки (представляющей любое количе+ ство символов или ни одного символа), что часто приводит к неожиданным и нежела+ тельным результатам. Можно сформулировать два практических правила:

регулярное выражение почти никогда не следует начинать с комбинации како+ го+либо символа и звездочки;

шаблоны .* или .+ в середине регулярного выражения совпадают с макси+ мально возможным количеством подстрок в строке.

Квантификаторы

Квантификаторы (quantifiers) используются для установки ограничений и диапазо+ нов количества совпадающих символов. Например, выражение \s{2,3} соответству+ ет двум или трем пробелам (или другим символам, упомянутым в приведенной выше таблице шаблонов). Символ \s заставляет регулярное выражение искать пробелы, а фигурные скобки, окружающие цифры 2 и 3, заставляют использовать эти цифры в качестве диапазона: от 2 до 3 символов. Первый символ в фигурных скобках пред+ ставляет минимальную границу диапазона, а второй ++++++ максимальную. Диапазоны квантификаторов функционируют подобно диапазонам в классах символов, но их синтаксис несколько отличается: сначала пишется искомый символ, а затем в фигур+ ных (а не в квадратных) скобках указываются числа, разделенные запятой.

Опуская числа максимума или минимума (но оставляя запятую), можно задать диа+ пазоны ‘‘не менее’’ или ‘‘не более’’ соответственно. Например, запись {2,} означает ‘‘не мене двух’’, а {,3} ++++++ ‘‘не более трех’’. В этих случаях применяются те же правила, что и для оператора *.

Можно создавать весьма мощные выражения, используя несколько из описанных специальных символов. Например, можно указать количество определенных под+ строк в строке, задав это число в фигурных скобках: выражение \b\w{5}\b соответ+ ствует слову из пяти букв.

Сводная характеристика метасимволов

В следующей таблице представлено краткое описание рассмотренных метасимволов:

Метасимвол

Значение

 

 

[abc]

Любой из символов a, b или c

[^abc]

Один любой символ a, b или c

[a-z]

Один любой ASCII-символ между a и z включительно

\d и \D

Цифра и не цифра

\w и \W

Символы “слово” и “не слово”

\s и \S

Символ пустого пространства и его альтернатива

\b

Граница между символами \w и \W

Надежный и понятный код 247

Окончание таблицы

Метасимвол

Значение

 

 

.

Любой символ (кроме символа новой строки)

(abc)

Фраза “abc” как группа символов

?Предыдущий символ или группа символов может присутствовать 0 или 1 раз

+Предыдущий символ или группа символов может присутствовать 1 или несколько раз

*Предыдущий символ или группа символов может присутствовать 0 или несколько раз

{x,y}

Предыдущий символ или группа символов присутствует от x до y раз

{,y}

Предыдущий символ или группа символов присутствует не более y раз

{x,}

Предыдущий символ или группа символов присутствует не менее x раз

{x}

Предыдущий символ или группа символов присутствует x раз

^Начало строки

$ Конец строки

Проверка ввода данных

Одним из наиболее распространенных элементов, вводимых пользователями в Web+ приложениях, является e+mail+адрес, который благодаря своему уникальному формату представляет отличный пример для проверки данных формы. Во+первых, нелегко оп+ ределить длину адреса, потому что обычно неизвестно, какие символы используются в именной части адреса. Во+вторых, адрес содержит знак @, который обычно не встреча+ ется в других распространенных элементах данных. И в+третьих, обязательно присутст+ вие .com, .net, .org или любой другой подстроки допустимой в конце доменного имени.

Адрес электронной почты столь часто запрашивается в Web+формах, потому что он может оказаться единственной контактной информацией, предоставляемой поль+ зователем, и если по какой+либо причине адрес введен некорректно, возможность связаться с данным пользователем теряется.

Существует множество побудительных мотивов для проверки e+mail+адресов, а также множество различных программ проверки. Некоторые из них очень сложны и способны проверять адреса с высокой степенью точности, другие весьма просты и их точность на+ много ниже. Одна из простейших программ лишь проверяет наличие единственного зна+ ка @ в адресе ++++++ очевидно, что если этого знака нет, то адрес не может быть корректным, с другой стороны, если знак @ встречается несколько раз, то такой адрес также некор+ ректен. Хотя само по себе наличие одного знака @ не гарантирует корректности адреса.

Регулярные выражения удобны для создания подпрограмм проверки адресов, по+ тому что с их помощью можно реализовать множество вариантов условной проверки. Например, в любом e+mail+адресе перед и после знака @ должны присутствовать ка+ кие+либо символы. Справа от символа @ должна быть точка (.), перед и после которой также присутствуют какие+либо символы. Кроме того, существуют символы, которые не допускается использовать в e+mail+адресах (например, пробел). Образцы регуляр+ ных выражений можно конструировать так, чтобы они весьма точно определяли аномалии в структуре адреса:

^[^@ ]+@[^@ ]+\.[^@ \.]+$

248 Глава 5

Этот образец на первый взгляд может показаться бессмысленным; его следует раз+ вернуть. В следующей таблице описываются по порядку все символы и их значения.

Символ

Значение

^В начале строки...

[^@ ]

...один любой символ, кроме @ или пробела,

+...который встречается один или несколько раз

@Символ @

[^@ ] Затем один любой символ, кроме @ или пробела,

+...который встречается один или несколько раз

\. Точка (которую необходимо экранировать с помощью обратной косой черты) [^@ \.] Любой символ, кроме @, пробела или точки,

+...который встречается один или несколько раз. Сразу за его последним вхождением должен быть...

$

...конец строки

Данный образец прост, но ни в коем случае не идеален. Существуют гораздо бо+ лее сложные процедуры анализа e+mail+адресов и URL, которые могут быть очень запутанными.

Рассмотрим на примере использование данного регулярного выражения в функ+ ции ereg() для проверки вводимых e+mail+адресов.

Практика Проверка e-mail-адресов

1. Введите в HTML+редакторе следующий код:

<html>

<head><title></title></head>

<body>

<?php //email_validation.php

if (isset($_POST['posted'])) {

$email = $_POST['email'];

$theresults = ereg("^[^@ ]+@[^@ ]+\.[^@ \.]+$", $email, $trashed);

if ($theresults) { $isamatch = "корректен";

} else {

$isamatch = "некорректен";

}

echo "Введенный для проверки адрес $email " . $isamatch;

}

?>

<form action="email_validation.php" method="POST">

<input type="hidden" name="posted" value="true">

Введите e-mail-адрес для проверки:

<input type="text" name="email" value="name@example.com"> <input type="submit" value="Проверить">

</form>

</body>

</html>

Надежный и понятный код 249

2.Сохраните данный файл как email_validation.php и закройте его.

3.Запустите сценарий и проверьте его работу как с ‘‘хорошими’’, так и с ‘‘плохими’’ e+mail+адресами. На рис. 5.4 показан примерный результат после ввода некор+ ректного адреса; неправильно введенный адрес отображается вверху страницы.

Рис. 5.4.

Как это работает

Сравнение введенной строки с образцом выполняется с помощью функции ereg(). Когда данные формы отправляются, введенная пользователем строка пере+ дается в переменную $email (из переменной $_POST['email']). Затем для провер+ ки корректности данной строки используется функция ereg(). Если адрес правиль+ ный, то в переменную $isamatch записывается значение ‘‘корректен’’, в противном случае ++++++ ‘‘некорректен’’. Затем результат отображается в браузере пользователя.

<?php //email_validation.php

if (isset($_POST['posted'])) { $email = $_POST['email'];

$theresults = ereg("^[^@ ]+@[^@ ]+\.[^@ \.]+$", $email, $trashed);

if ($theresults) { $isamatch = "корректен";

} else {

$isamatch = "некорректен";

}

echo "Введенный для проверки адрес $email " . $isamatch;

}

?>

250 Глава 5

Чтобы показать пользователю необходимый формат вводимых данных, в поле формы предустановлен e+mail+адрес по умолчанию (предполагается, что пользователь понимает, что этот адрес необходимо заменить реальным значением).

Приведенного выше сценария вполне достаточно для проверки e+mail+адресов, хо+ тя он не идеален. Он позволяет вводить после знака @ недопустимые в доменном имени символы (например, *) и, по сути, не проверяет существование введенного до+ менного имени. Наилучшим способом проверки e+mail+адреса является передача этого адреса серверу; даже правильно сформированный e+mail+адрес является некоррект+ ным, если сервер, с которым он связан, не принимает его.

Использование регулярных выражений для проверки URL-указателей

Доменные имена и полные URL (Uniform Resource Locator ++++++ унифицированный указатель ресурсов) представляют собой интересный пример для применения поис+ ковых возможностей регулярных выражений. Структура доменного имени проста ++++++

имя, за которым следует точка и расширение доменного имени (например, .com,

.net, .org и т.д.), но существуют правила, запрещающие использование в доменном имени некоторых символов; кроме того, включать в доменное имя префикс www (или другой) необязательно. URL+указатели включают в себя доменные имена и префикс http://, а в состав полного URL также может быть включен путь (имена каталогов, разделенных косой чертой), имя файла и строка запроса, которая добавляется в ко+ нец URL. Существует немало вариантов доменных имен и URL, поэтому, как и в слу+ чае e+mail+адресов, важно правильно их понимать.

Ниже описан формат унифицированного указателя ресурсов (URL):

протокол (например, ftp или http);

доменное имя или имя сервера (например, wrox.com; www использовать необя+ зательно);

необязательный в некоторых случаях каталог и путь к файлу (каталог и имя файла, разделенные символом косой черты, например, images/myimage.gif);

необязательная строка запроса (начинается со знака вопроса, за которым сле+ дует одна или несколько пар имя/значение).

Рассмотрим код регулярного выражения:

^[a-zA-Z0-9]+://[^ ]+$

Аналогично ключевой строке в предыдущем примере, данное выражение можно использовать в следующем коде:

$theresults = ereg("^[a-zA-Z0-9]+://[^ ]+$", $intext, $trashed);

В следующем примере проверяется корректность формата URL+указателей.

Практика Проверка корректности формата URL

1. Запустите редактор Web+страниц и введите следующий код:

<html>

<head></head>

<body>

<?php //url_validate.php

if (isset($_POST['posted'])) { $url = $_POST['url'];

Надежный и понятный код 251

$theresults = ereg("^[a-zA-Z0-9]+://[^]+$", $url, $trashed);

if ($theresults) { $isamatch = "корректен";

} else {

$isamatch = "некорректен";

}

echo "Введенный URL $url " . $isamatch;

}

?>

<form action="url_validate.php" method="POST">

<input type="hidden" name="posted" value="true">

Введите URL для проверки:

<input type="text" name="url" value="http://www.example.com" size="30"> <input type="submit" value="Проверить">

</form>

</body>

</html>

2.Сохраните созданный файл как url_validate.php и закройте его.

3.Запустите сценарий и проверьте его работу путем ввода как корректных, так и некорректных URL+указателей.

На рис. 5.5 показан примерный результат работы данного сценария после ввода некорректно сформированного URL+указателя.

Рис. 5.5.

Как это работает

Аналогично email_validation.php данный сценарий главным образом основывает+ ся на единственном регулярном выражении, которое обрабатывается функцией ereg():

$theresults = ereg("^[a-zA-Z0-9]+://[^]+$", $url, $trashed);

252 Глава 5

Это регулярное выражение совпадает с корректными URL+указателями, но, к со+ жалению, оно также совпадает со многими другими строками, которые не являются корректными URL. Как и в случае многих образцов регулярных выражений, выясня+ ется, что добиться идеального совпадения с образцом, не затрачивая при этом боль+ шого количества времени, очень трудно (некоторые образцы проверки URL насчи+ тывают сотни символов в длину и, несмотря на это, не являются идеальными). Главная цель заключается в том, чтобы устранить наиболее распространенные ошибки. В конце концов, любые незначительные изменения в составе корректного URL+указа+ теля (или e+mail+адреса) могут сделать регулярное выражение бессмысленным ++++++ что идеально сегодня, завтра может оказаться быть неприемлемым.

Использование регулярных выражений для проверки параметров файловых путей

Файловые системы и PHP+функции для работы с файлами и каталогами обсужда+ ются в главе 7. Здесь мы вкратце рассмотрим те функции регулярных выражений, ко+ торые могут оказаться полезными для защиты данных, сохраняемых в файлах (именно в файлах ++++++ базы данных не единственный способ постоянного хранения данных; для длительного хранения информации приложений часто используются обычные текстовые файлы).

Термин постоянные применительно к сохраняемым данным используется для обозначения данных, которые не теряются даже после закрытия приложения или выключения системы.

Эти функции (а также примеры кода с их использованием) упрощают проверку данных, которые представляют собой имена файлов или каталогов, и поэтому могут оказаться очень полезными для ограничения доступа к определенным каталогам и файлам. Можно разрешить доступ пользователей к определенным файлам и катало+ гам, однако к некоторым из них доступ должен иметь только администратор.

В следующем примере путем удаления конфиденциальной информации из файло+ вых путей запрещается просмотр обычными пользователями дерева каталогов. В дан+ ном случае можно эффективно использовать вариант функции ereg() ++++++ функцию ereg_replace().

Чтобы решить эту задачу, необходимо составить образец, который с помощью функции ereg_replace() позволяет удалить из строки символы "\", "/" или "../". В Unix+системах в качестве ограничивающего символа используется косая черта, то+ гда как в Windows применяются символы обратной косой черты, а в MacOS использу+ ется двоеточие. Кроме того, данный код будет удалять любые абсолютные пути, начи+ нающиеся с символа "/" или [A-Z].

Практика Предотвращение доступа к секретным файлам

1. Откройте редактор Web+страниц и введите следующий код:

<html>

<head><title></title></head>

<body>

<?php //clean_path.php

Соседние файлы в папке web - tec