Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Структура. Сейчас будет сложное описание, мне оно и самому не нравится.

Читайте также:
  1. I. Общая структура Ig
  2. II. Структура и состав кадастровых сведений Реестра объектов недвижимости
  3. II. СТРУКТУРА КРИЗИСА
  4. III. Структура и управление отделом
  5. III. Структура регионального центра социального преображения
  6. III. Структура управления службой (отделом)
  7. IV. Организационная структура Совета

Сейчас будет сложное описание, мне оно и самому не нравится.

Эта вещь необходима для сложных запросов. Например, вам надо, чтобы в тексте были либо только маленькие буквы, либо только большие, либо только цифры. Класс символов "[a-zA-Z0-9]" не подходит. Тогда пишем такое:

if (ereg("[a-z]+|[A-Z]+|[0-9]+", $text))...

Вертикальная черта — знак "или" регулярных выражений (знака "и", естественно, не существует — это и есть само регулярное выражение). Разделенные вертикальной чертой шаблоны в официальной документации называются альтернативными ветвями (это подразумевает ветвление, т.е. наличие вложенных альтернативных ветвей). Программа сравнивает со строкой все ветви (проходясь по их ряду слева направо), до первого совпадения (это важно учесть, если у вас сложное выражение со вложенными ветвями). Для разделения уровней и отделения этого дерева альтернатив от остального шаблона используются обычные скобки. Если те же большие/маленькие буквы/цифры надо искать внутри контейнера тегов:

 

if (ereg("<tag>([a-z]+|[A-Z]+|[0-9]+)</tag>", $text))...

Скобки называются subpattern (вложенный шаблон). И используются не только для сложных вариантов шаблонов, но и для гибкой замены фрагментов текста или получения их в переменную. К примеру, для печатной версии текста дублируем адреса ссылок текстом в скобках:

 

ereg_replace("<a href=([^>]+)>[^<]+</a>", " [1]", $text);

Первые скобки — первый вложенный шаблон — можно получить "на выходе" через обозначение "n" (поскольку обратный слэш в php и многих других языках используется для спецсимволов, надо поставить перед ним еще один такой же, чтобы прогамма понимала его буквально). Под нулевым номером — вся совпавшая строка. У себя в печатной версии статьи я не пишу ссылки сразу в тексте, а делаю их список в конце примерно так:

if (ereg("<a href=([^>]+)>([^<]+)</a>", $text, $match)) {for ($a=0;$a<sizeof($match[0]);$a++) { $b = $a+1; $text = str_replace($match[0][$a], $match[0][$a]." [$b]", $text); $match[1][$a] = "$b) ". $match[1][$a]; }; $text.= "<br><h2>Ссылки, использованные в выпуске:</h2>". implode("<br>", $match[1]); };

Функция ereg (и eregi), если ей указать в третьем параметре переменную, то туда будут записаны все подстроки в виде двухмерного массива [1].

Это, собственно, все. Дальше нужно только уметь составлять шаблоны. Приведу несколько примеров.

1. Переписывание адресов сервером Apache [2] (Apache работает со стандартом POSIX).

2. Поиск по базе данных [3]: из пользовательского поискового запроса делается sql-запрос. Если отбросить создание статистики поиска (сколько найдено всего, сколько по каждому слову), то получится, что необходимо всего 6-7 строк кода. Там же описана и подсветка слов в результатах поиска. Кстати, важное замечание: перед тем, как вырезать короткие слова из строки я заменяю пробелы между словами на двойные. Почему? Потому что совпадающие с шаблоном строки не должны наезжать друг на друга.

Объясню подробнее. Если в шаблоне нет никаких якорей, система проходится по тексту слева направо, и если найдено совпадение, кидает его в какие-то переменные, а затем перескакивает на следующий символ после совпавшего фрагмента. Мы ищем по шаблону "пробел, два непробела, пробел", а пробелы одиночные. Программа находит "пробел-короткое слово-пробел", заменяет это на один пробел, а затем перескакивает на... первую букву следующего слова. Это не пробел, поэтому даже если следующее слово тоже короткое, оно под шаблон не подойдет. Поэтому-то и надо предварительно заменить пробелы на двойные.

3. Как хранить новости в файлах и не бегать циклом по дате:

$handle=opendir($newsdir);while ($file = readdir($handle)) { if (is_file($file) && ereg("^[0-9]{6}.txt$", $file)) print ("<p align=justify><b>". ereg_replace("^([0-9]{2})([0-9]{2})([0-9]{2}).txt$", "1.2.203", $file). "</b> ". implode("", file($file)). "</p>");closedir($handle);

 

4. Проверка правильного написания email-а:

if (!eregi("^[a-z0-9._-]+@[a-z0-9._-]+.[a-z]{2,4}$", $email)) print("Bad email: "$email"");

 

PCRE

Поговорим о регулярных выражениях совместимых с Perl (Perl compatible regular expressions — PCRE).

Самое главное их преимущество перед POSIX - это возможность "жадного" поиска. Вопросительный знак в PCRE выступает еще и как минимизатор квантификатора:

.*?

Найдет минимальную подходящую строку. Вроде бы ничего особенного? Нет, это очень особенная вещь. Например, какой пример я приводил в прошлом выпуске про печатную версию текста?

$text = ereg_replace("<a +href=([^>]+)>[^<]+</a>", " [1]", $text);

То есть, внури ссылки не должно быть тегов (например "<a href=...><b>...</b></a>"). Если же сделать так:

$text = ereg_replace("<a +href=([^>]+)>.*</a>", " [1]", $text);

Тогда мы получим... Правильно, весь текст между началом первой и концом последней ссылки.

Все проблемы снимает жадный поиск.

$text = preg_replace("/<as+href=(.*?)>.*?</a>/", " [1]", $text);

Программа подберет для всех ссылок минимальную подходящую строку, т.е. только до тега "</a>". Описывать значение такой особенности PCRE нет смыла — оно огромное.:) Идем дальше.

Цифры теперь можно обозначить не как "[0-9]", а просто "d". Не-цифры ("[^0-9]") как "D". Очень удобно. Вот остальные обозначения:

w [a-z0-9]
W [^a-z0-9]
s [ ]
S [^ ]


Строка шаблона, как вы уже заметили, начинается и заканчивается слэшами. После второго идут параметры:

i регистронезависимый поиск
m многостроковый режим. По умолчанию PCRE ищет совпадения с шаблоном только внутри одной строки, а символы "^" и "$" совпадают только с началом и концом всего текста. Когда этот параметр установлен, "^" и "$" совпадают с началом и концом отдельных строк.
s символ "." (точка) совпадает и с переносом строки (по умолчанию — нет)
A привязка к началу текста
E заставляет символ "$" совпадать только с концом текста. Игнорируется, если установлен парамерт m.
U Инвертирует "жадность" для каждого квантификатора (если же после квантификатора стоит "?", этот квантификатор перестает быть "жадным").
e Строка замены интерпретитуется как PHP код.

Естественно, регистр в параметрах имеет значение. Остальное о них можно прочесть в руководстве по php.

Теперь о функциях PCRE.

Функция preg_match в отличие от ereg ищет только первое совпадение. Если нужно найти все совпадения и как-то обработать их результаты (но не напрямую через preg_replace), нужно пользоватьсяpreg_match_all. Параметры этой функции те же.

Из полезного отмечу функцию preg_quote, которая вставляет слэши перед всеми служебными символами (например, скобками, квадратными скобками и т.п.), чтобы те воспринимались буквально. Если у вас есть какой-либо ввод информации пользователем, и вы проверяете его через PCRE, лучше перед этим закомментировать служебные символы в пришедшей переменной (мало ли что он там напишет, это ведь по определению злобный хакер).


Дата добавления: 2015-08-18; просмотров: 61 | Нарушение авторских прав


Читайте в этой же книге: Примеры | Особенности пользовательских функций PHP | Переменное число параметров | Обработка ошибок и исключений в PHP | Открытие файла | Работа с БД MySQL через расширение mysql | Синтаксис DELETE | Что такое cookies и как с ними работать | Dothings.php | Secretplace.php V2 |
<== предыдущая страница | следующая страница ==>
Регулярные выражения (regexp).| Preg_match

mybiblioteka.su - 2015-2024 год. (0.007 сек.)