РНР программирование

 

     Главная         Программа телепередач, энциклопедии и многие другие справочные материалы

 

 

стр.  1. 2. 3. 4. 5. 6. 7. 8.

 

Например, нам необходимо "сжать" текст, убрав из него все лишние пробелы и символы перевода строки:

<?php

$text = "there     is\t\n\t\t some text  \n  \t just  \n\n\n for     test";

echo "<b>Перед заменой:</b>\n$text\n\n";

$text = preg_replace("/(\n \s{2,})/"," ",$text);

echo "<b>После замены:</b>\n$text";

?>

Результатом работы данной программы будет следующий текст:

Перед заменой:

there     is

         some text

     just

 

 

 for     test

 

После замены:

there is some text just for test

Как видите - всего одна строчка позволила нам решить достаточно нетривиальную в обычной практике задачу. Объяснять само регулярное выражение я не буду, если вы внимательно прочитали предыдущий выпуск - понять его вам будет несложно.

Однако основная прелесть этой функции, которая и придает ей всю ее мощь - это тот факт, что вы можете ссылаться на результаты поиска при генерации замещающего текста. В качесте примера покажу, как можно очень быстро и элегантно решить задачу, которая возникает достаточно часто - конвертация дат из одного формата в другой. Как вы знаете, на Западе обычно используется формат mm/dd/yyyy, тогда как у нас обычно - dd.mm.yyyy. Следующий пример осуществляет конвертацию дат между этими форматами в заданном тексте:

<?php

$text = 'Today is 11/16/2001';

$text = preg_replace("/(\d{2})\/(\d{2})\/(\d{4})/","\\2.\\1.\\3",$text);

echo $text;

?>

Результат работы этой программы:

Today is 16.11.2001

Обратите внимание на текст, используемый для замены. В нем использованы т.н. backreferences, т.е. ссылки на найденный ранее текст. Всего таких ссылок может быть не более 100 с номерами от 0 до 99 (соответственно в тексте они выглядят как \0, \1, \2 ... \99). Backreference с номером 0 будет заменена на весь найденный текст, \1 - на текст, найденный первым внутренним регулярным выражением, \2 - вторым и т.д. Номерв внутренним регулярным выражениям присваиваются по мере их находжения в тексте, т.е. слева-направо. В нашем случае \1 - это месяц, \2 - день, \3 - год.

Помимо стандартного синтаксиса регулярных выражений, в PHP, совместно с функцией preg_replace() используется еще один дополнительный модификатор - 'e'. Его использование заставляет PHP рассматривать текст замены не как текст, а как PHP код, что дает возможность еще больше расширить сферу применения этой функции в вашем коде. Следующий пример демонстрирует использование этого модификатора - он производит замену всех целых десятичных чисел в тексте на их шестнадцатиричные эквиваленты:

<?php

$text = "123 234 345 456 567";

$text = preg_replace("/\d+/e","'0x'.dechex('\\0')",$text);

print_r($text);

?>

Результатом работы этой программы будет:

0x7b 0xea 0x159 0x1c8 0x237

И еще одно. Функция preg_replace() также умеет работать с массивами регулярных выражений. Т.е. это позволит вам осуществить поиск и замену сразу по множеству условий! В качестве примера приведу фрагмент кода, описанный в PHP Manual и осуществляющий конвертацию HTML документа в текст при помощи всего лишь одного вызова preg_replace()!

// $document should contain an HTML document.

// This will remove HTML tags, javascript sections

// and white space. It will also convert some

// common HTML entities to their text equivalent.

 

$search = array ("'<script[^>]*?>.*?</script>'si",  // Strip out javascript

                 "'<[\/\!]*?[^<>]*?>'si",           // Strip out html tags

                 "'([\r\n])[\s]+'",                 // Strip out white space

                 "'&(quot #34);'i",                 // Replace html entities

                 "'&(amp #38);'i",

                 "'&(lt #60);'i",

                 "'&(gt #62);'i",

                 "'&(nbsp #160);'i",

                 "'&(iexcl #161);'i",

                 "'&(cent #162);'i",

                 "'&(pound #163);'i",

                 "'&(copy #169);'i",

                 "'&#(\d+);'e");                    // evaluate as php

 

$replace = array ("",

                  "",

                  "\\1",

                  "\"",

                  "&",

                  "<",

                  ">",

                  " ",

                  chr(161),

                  chr(162),

                  chr(163),

                  chr(169),

                  "chr(\\1)");

 

$text = preg_replace ($search, $replace, $document);

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

Функция preg_replace_callback()

Синтаксис:

mixed preg_replace_callback (mixed pattern, mixed callback, mixed subject [, int limit])

Эта функция является расширенной версией функции preg_replace() (хотя, казалось бы, чего еще можно пожелать?). Единственным отличием ее от preg_replace() является то, что в качестве текста для замены в ней задается не сам текст, а имя функции, которая будет производить обработку найденного текста и возвращать замещающий текст. Т.е. с использованием этой функции мощь инструментария PHP по обработке текста становится поистине безграничной! В качестве примера хочу привести фрагмент кода, который выполняет работу, аналогичную той, что производится механизмом сессий в PHP: добавление дополнительного аргумента (идентификатора сессии) к каждой ссылке внутри HTML документа.

<?php

// Список тегов и аттрибутов, к котроым необходимо

// добавить дополнительный параметр.

// Формат строки:

// <имя тега>[ <имя аттрибута>]+

// Т.е. сначала идет имя тега, а затем, через пробел,

// имена одного или нескольких аттрибутов.

$tagsList = array(

    'a href',

    'area href',

    'frame src',

    'input src',

    'img src',

    'form action'

);

// Идентификатор сессии

$sid = 12345;

// HTML документ для обработки. Здесь, в качестве примера

// мы берем его из внешнего файла, но вообще-то метод

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

$document = join('',file('document.html'));

// Начинаем обработку всех тегов, указанных в массиве $tagsList

foreach($tagsList as $tag)

{

// Разделяем список аттрибутов на составляющие

    $attrs = explode(' ',$tag);

// Получаем имя тега (в массиве $attrs остается лишь список аттрибутов)

    $tag = array_shift($attrs);

// Выполняем "патч" всех имеющихся в документе ссылок, содержащихся

// в каждом из аттрибутов текущего тега

    foreach($attrs as $attr)

        $document = preg_replace_callback("/<".$tag.".+?".$attr."=[\'\"](.+?)[\'\"]/si",

                                          'callback',$document);

};

// Выводим документ и выходим

echo $document;

exit();

// Эта функция будет вызываться для каждой найденной

// ссылки в тексте HTML документа.

// На входе она получает результат поиска (массив,

// аналогичный возвращаемому функцией preg_match()).

// На выходе из функции должна быть строка с текстом замены.

function callback($data)

{

// Регулярное выражение, использованное для поиска находит полные

// HTML теги, содержащие аттрибуты, в которых могут находиться

// URL адреса. Поскольку текст, возвращаемый данной функцией будет

// использован для замещения всего найденного фрагмента текста -

// нам необходимо взять полный текст, чтобы не потерять его при

// дальнейшей обработке. Он будет возвращен без изменений, если

// окажется, что аттрибут не содержит URL адреса.

    $href = $data[0];

// Используем функцию PHP для разбора URL адреса на составляющие.

// В качестве "исходного материала" передаем содержимое интересующего

// нас аттрибута, найденного внутренним регулярным выражением.

// Подробнее о том, что возвращает эта функция см. PHP Manual.

    $parts = parse_url($data[1]);

// Мы должны добвлять идентификатор сессии только к ссылкам, которые

// являются "локальными" для данного сайта. Т.е. мы не должны обрабатывать:

//  - полные URL адреса (<a href="http://www.php.net/">)

//  - указатели на "якоря" внутри страницы (<a href="#part2">)

    if ((!isset($parts['scheme'])) &&   // Если URL содержит идентификатор

        (!isset($parts['host'])) &&     // протокола или имя домена - это

                                        // полный URL адрес.

        (substr($data[1],0,1)!='#'))    // Если URL начинается с символа '#'

                                        // то это ссылка на "якорь" внутри страницы

    {

// Берем путь к странице, указанный в URL и добавляем разделитель для параметров

// потому что нам необходимо будет добавить по крайней мере 1 параметр

        $href = $parts['path'].'?';

// Если в этом URL уже были какие-либо параметры - добавляем их и добавляем

// разделитель. Заметьте, что в качестве разделителя используется &amp;, а не &,

// это позволяет нам добиться совместимости с XHTML.

        if (isset($parts['query']))

            $href .= $parts['query'].'&amp;';

// Добавляем наш собственный параметр - идентификатор сессии

        $href .= 'sid='.$GLOBALS['sid'];

// Если в оригинальном URL была ссылка на фрагмент документа - возвращаем ее

// на место.

        if (isset($parts['fragment']))

            $href .= '#'.$parts['fragment'];

// "Вставляем" новый URL на место того, который был там раньше

        $href = str_replace($data[1],$href,$data[0]);

    };

// Возвращаем результат

    return($href);

};

?>

Пример может показаться немного громоздким, но это исключительно из-за обилия комментариев.

Функция preg_split()

Синтаксис:

array preg_split (string pattern, string subject [, int limit [, int flags]])

Данная функция выполняет действие, аналогичное функциям split() и explode() - разбивает строку на части по какому-либо признаку и возвращает массив, содержащий части строки. Однако ее возможности по заданию правил разбиения больше, чем у этих функций, потому что в ее основе лежит механизм регулярных выражений, в мощи которого, я надеюсь, вы уже смогли убедиться. Если говорить более конкретно, то строка subject разбивается на части по разделителю, заданному регулярным выражением pattern. При этом количество фрагментов может быть ограничего необязятельным параметром limit. Кроме того эта функция поддерживает необязательный параметр flags, который позволяет в некоторой степени контролировать процесс разбиения строки.

Параметр flags может принимать следующие значения (или их комбинации с использованием знака ' '):

  • PREG_SPLIT_NO_EMPTY - возвращать только непустые части строк, полученные в результате разбиения.

  • PREG_SPLIT_DELIM_CAPTURE - возвращать также результаты поиска по внутренним регулярным выражениям.

Рассмотрим пару примеров. Для начала - выражение, которое разбивает произвольный текст на отдельные слова:

<?php

$text = join('',file('my_text.txt'));

$words = preg_split("/\s+/s",$text);

print_r($words);

?>

Как видите - мы получаем содержимое файла 'my_text.txt' в виде строки, разбиваем его на отдельные слова и выводим содержимое массива слов, чтобы убедиться, что все работает правильно.

Еще один пример производит разбиение заданного слова на буквы (он описан в PHP Manual):

<?php

$str = 'string';

$chars = preg_split('//',$str,-1,PREG_SPLIT_NO_EMPTY);

print_r($chars);

?>

Значение -1 для параметра limit означает отсутствие лимита.

Функция preg_quote()

Синтаксис:

string preg_quote (string str [, string delimiter])

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

. \ + * ? [ ^ ] $ ( ) { } = ! < >   :

Все эти символы, встречающиеся в строке будут "отквочены" путем добавления символа '\' непосредственно перед каждым из них. Модифицированная таким образом строка будет возвращены в качестве результата.

Эта фцнкция также имеет необязательный параметр delimiter. Если этот параметр задан, то символ, переданный в качестве этого параметра тоже будет "отквочен" данной функцией.

Функция preg_grep()

Синтаксис:

array preg_grep (string pattern, array input)

Действие этой функции похоже на действие команды grep в Unix. Она ищет текст по регулярному выражению pattern, в массиве input и возвращает новый массив, содержащий только элементы, в которых были найдены совпадения с заданным регулярным выражением. К примеру у нас есть файл,

главная                                                                                                                   стр.  1. 2. 3. 4. 5. 6. 7. 8.

 

1. Что такое PHP?

1. 1. Применение РНР при программировании сайтов

1.2. Программа регистрации и авторизации на вашем сайте

1.3. Программа регистрации и авторизации на сайте с шифрованием пароля

2. Глава посвящена программированию
вообще и программированию в частности
сайтов

3. MySQL элементы управления и взаимодействие с PHP

4. Русский перевод файла "httpd.conf" Для Apache 2.0

5. Русский перевод файла "php.ini"