На главную Назад
Добро пожаловать, уважаемый посетитель!

 

ГЛАВА 8

Строки ирегулярные выражения

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

Поиск пошаблону позволяет не только находитьопределенные фрагменты текста, но изаменять их другими фрагментами. Одним изстандартных примеров поиска по шаблонуявляются команды поиска/замены в текстовыхредакторах - например, в 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".

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

Листинг8.1.Выводэлементов массива $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;

Привыполнении сценария в листинге 8.1 будетполучен следующий результат:

http://www.apress.comhttp://www apress com

ereg_replace( )

Функцияereg_replace( ) ищет в заданной строке совпадениедля шаблона и заменяет его новым фрагментом.Синтаксис функции ereg_replace( ):

string ereg_replace (stringшаблон,string замена, string строке)

Функцияereg_replace( ) работает по тому же принципу, что иereg( ), но ее возможности расширены отпростого поиска до поиска с заменой. Послевыполнения замены функция возвращаетмодифицированную строку. Если совпадения

отсутствуют,строка остается в прежнем состоянии.Функция ereg_replace( ), как и еrеg( ), учитываетрегистр символов. Ниже приведен простойпример, демонстрирующий применение этойфункции:

$copy_date = "Copyright1999":

$copy_date =ereg_replace("([0-9]+)". "2000", $copy_date);

print $copy_date: //Выводится строка "Copyright 2000"

У средствпоиска с заменой в языке РНР имеется однаинтересная возможность - возможностьиспользования обратных ссылок на частиосновного выражения, заключенные в круглыескобки. Обратные ссылки похожи на элементынеобязательного параметра-массивасовпадения функции еrеg( ) за однимисключением: обратные ссылки записываютсяв виде \0, \1, \2 и т. д., где \0 соответствует всейстроке, \1 - успешному совпадению первогоподвыражения и т. д. Выражение можетсодержать до 9 обратных ссылок. В следующемпримере все ссылки на URL в тексте заменяютсяработающими гиперссылками:

$url = "Apress (http://www.apress.com");

$url = ereg_replace("http://(([A-Za-z0-9.\-])*)","<a href=\"\\0\">\\0</a>", $url);

print $url;

// Выводитсястрока:

// Apress (<a href="http://www.apress.com">http://www.apress.com</a>)

eregi( )

Функция eregi( )ищет в заданной строке совпадение дляшаблона. Синтаксис функцииeregi():

int eregi(string шаблон, string строка [, array совпадения])

Поискпроизводится без учета регистраалфавитных символов. Функция eregi( ) особенноудобна при проверке правильности введенныхстрок (например, паролей). Использованиефункции eregi( ) продемонстрировано вследующем примере:

$password = "abc";

if (! eregi("[[:alnum:]]{8.10},$password) :

print "Invalidpassword! Passwords must be from 8 through 10 characters in length.";

endif;

// Врезультате выполнения этого фрагментавыводится сообщение об ошибке.

// посколькудлина строки "abc" не входит вразрешенный интервал

// от 8 до 10символов.

eregi_replace( )

Функцияeregi_replасе( ) работает точно так же, как ereg_replace(), за одним исключением: поиск производитсябез учета регистра символов. Синтаксисфункции ereg_replace( ):

string eregi_replace(string шаблон,string замена, string строка)

split( )

Функция split( )разбивает строку на элементы, границыкоторых определяются по заданному шаблону.Синтаксис функции split( ):

array split(string шаблон, string строка [, int порог])

Необязательныйпараметр порог определяет максимальноеколичество элементов, на которые делитсястрока слева направо. Если шаблон содержиталфавитные символы, функция spl it( ) работаетс учетом регистра символов. Следующийпример демонстрирует использованиефункции split( ) для разбиения канонического IP-адресана триплеты:

$ip ="123.345.789.000"; // Канонический IP-адрес

$iparr =split ("\.", $ip) // Поскольку точка являетсяслужебным символом.

// еенеобходимо экранировать.

print "$iparr[0]<br>"; // Выводит "123"

print "$iparr[1]<br>"; // Выводит "456"

print "$iparr[2]<br>"; // Выводит "789"

print "$iparr[3]<br>"; // Выводит "000"

spliti( )

Функцияspliti( ) работает точно так же, как ее прототипsplit( ), за одним исключением: она неучитывает регистрасимволов. Синтаксис функции spliti( ):

array spliti(string шаблон, string строка [, int порог])

Разумеется,регистр символов важен лишь в том случае,если шаблон содержит алфавитные символы.Для других символов выполнение spliti( )полностью аналогично split( ).

sql_regcase( )

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

string sql_regcase(string строка)

Еслиалфавитный символ существует в двухвариантах (верхний и нижний регистры),выражение в квадратных скобках будетсодержать оба варианта; в противном случаеисходный символ повторяется дважды.Функция sql_regcase( ) особенно удобна прииспользовании РНР с программными пакетами,поддерживающими регулярные выражения водном регистре. Пример преобразованиястроки функцией sql_regcase( ):

$version = "php 4.0";

print sql_regcase($version);

// Выводитсястрока [Pp][Hh][Pp][ ][44][..][00]

Синтаксисрегулярных выражений в стиле Perl

Perl (http://www.perl.com)давно считается одним из самых лучшихязыков обработки текстов. Синтаксис Perlпозволяет осуществлять поиск и замену дажедля самых сложных шаблонов. Разработчики РHРсочли, что не стоит заново изобретать ужеизобретенное, а лучше сделать знаменитыйсинтаксис регулярных выражений Perlдоступным для пользователей РНР. Такпоявились функции для работы с регулярнымивыражениями в стиле Perl.

Диалектрегулярных выражений Perl не так уж сильноотличается от диалекта POSIX. В сущности,синтаксис регулярных выражений Perl являетсяотдаленным потомком реализации POSIX,вследствие чего синтаксис POSIX почтисовместим с функциями регулярных выраженийстиля Perl.

Оставшаясячасть этого раздела будет посвященакраткому знакомству с диалектом регулярныхвыражений Perl. Рассмотрим простой пример:

/food/

Обратитевнимание: строка food заключена между двумякосыми чертами. Как и в стандарте POSIX, выможете создавать более сложные шаблоны припомощи квантификаторов:

/fo+/

Этотшаблон совпадает с последовательностью fo,за которой могут следовать дополнительныесимволы о. Например, совпадения будутобнаружены в строках food, fool и fo4. Рассмотримдругой пример использованияквантификатора:

/fo{2,4}/

Шаблонсовпадает с символом f, за которым следуютот 2 до 4 экземпляров символа о. К числупотенциальных совпадений относятся строкиfool , fooool и foosball .

В регулярныхвыражениях Perl могут использоваться всеквантификаторы, упомянутые в предыдущемразделе для регулярных выражений POSIX.

Метасимволы

Одной изинтересных особенностей Perl являетсяиспользование метасимволовпри поиске. Метасимвол[Следует отметить, что авторское толкованиетермина <метасимвол> противоречит нетолько всем традициям, по и официальнойдокументации РНР. - Примеч.перев.] представляетсобой алфавитный символ с префиксом \ -признаком особой интерпретации следующегосимвола. Например, метасимвол \d можетиспользоваться при поиске денежных сумм:

/([d]+)000/

Комбинация \dобозначает любую цифру. Конечно, в процессепоиска часто возникает задачаидентификации алфавитно-цифровых символов,поэтому в Perl для них был определенметасимвол \w:

/<([\w]+)>/

Этот шаблонсовпадает с конструкциями, заключенными вугловые скобки, - например, тёгами HTML.Кстати, метасимвол \W имеет прямопротивоположный смысл и используется дляидентификации символов, не являющихсяалфавитно-цифровыми.

Еще одинполезный метасимвол, \b, совпадает сграницами слов:

/sa\b/

Посколькуметасимвол границы слова расположен справаот текста, этот шаблон совпадет в строкахsalsa и lisa, но не в строке sand. Противоположныйметасимвол, \В, совпадает с чем угодно, кромеграницы слова:

/sa\B/

Шаблонсовпадает в таких строках, как sand и Sally, но несовпадает в строке salsa.

Модификаторы

Модификаторызаметно упрощают работу с регулярнымивыражениями. Впрочем, модификаторов много,и в табл. 8.1 приведены лишь наиболееинтересные из них. Модификаторыперечисляются сразу же после регулярноговыражения - например, /string/i.

Таблица8.1. Примерымодификаторов

Модификатор

Описание

mФрагменттекста интерпретируется как состоящийиз нескольких <логических строк>. Поумолчанию специальные символы ^ и $совпадают только в начале и в концевсего фрагмента. При включении <многострочногорежима> при помощи модификатора m^ и $будут совпадать в начале и в конце каждойлогической строкивнутри фрагмента
sПосмыслу противоположен модификатору m -при поиске фрагмент интерпретируетсякак одна строка, а все внутренниесимволы новой строки игнорируются
iПоисквыполняется без учета регистра символов

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

Функции РНРдля работы с регулярными выражениями (Perl-совместимые)

В РНРсуществует пять функций поиска по шаблону сиспользованием Perl-совместимых регулярныхвыражений:

  • preg_match( );
  • preg_match_all( );
  • preg_replace( );
  • preg_split( );
  • preg_grep( ).

Эти функцииподробно описаны в следующих разделах.

preg_match( )

Функцияpregjnatch( ) ищет в заданной строке совпадениедля шаблона. Если совпадение найдено,возвращается TRUE, в противном случаевозвращается FALSE. Синтаксис функции pregjnatch( ):

int pregjnatch(string шаблон, string строка [, array совпадения})

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

$linе = "Vi isthe greatest word processor ever created!";

// Выполнитьпоиск слова "Vi" без учета регистрасимволов:

if (preg_match("/\bVi\b\i", $line, $matcn)) :

print "Match found!";

endif;

// Команда if в этом примере возвращает TRUE

preg_match_all( )

Функцияpreg_match_all( ) находит все совпадения шаблона взаданной строке.

Синтаксисфункции preg_match_all( ):

Int preg_match_all(string шаблон, string строка,array совпадения [, int порядок])

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

  • PREG_PATTERN_ORDER- используется по умолчанию, еслипараметр порядок не указан. Порядок,определяемый значением PREG_PATTERN_ORDER, напервый взгляд выглядит не совсем логично:первый элемент (с индексом 0) содержитмассив совпадений для всего регулярноговыражения, второй элемент (с индексом 1)содержит массив всех совпадений дляпервого подвыражения в круглых скобках ит. д.;
  • PREG_SET_ORDER -порядок сортировки массива несколькоотличается от принятого по умолчанию.Первый элемент (с индексом 0) содержитмассив с текстом, совпавшим со всемиподвыражениями в круглых скобках дляпервого найденного совпадения. Второйэлемент (с индексом 1) содержитаналогичный массив для второгонайденного совпадения и т. д.

Следующийпример показывает, как при помощи функцииpreg_match_al( ) найти весь текст, заключенныймежду тегами HTML <b>...</b>:

$user_info = "Name:<b>Rasmus Lerdorf</b> <br> Title: <b>PHP Guru</b>";

preg_match_all ("/<b>(.*)<\/b>/U",Suserinfo. $pat_array);

print $pat_array[0][0]." <br> ".pat_array[0][l]."\n":

Результат:

Rasmus Lerdorf

PHP Guru

preg_replace( )

Функцияpreg_repl ace( ) работает точно так же, как и ereg_replасе(), за одним исключением - регулярныевыражения могут использоваться в обоихпараметрах, шаблон и замена. Синтаксисфункции preg_replace( ):

mixed preg_replace(mixed шаблон, mixed замена,mixed строка [, int порог])

Необязательныйпараметр порог определяет максимальноеколичество замен в строке. Интересный факт:параметры шаблон и замена могутпредставлять собой масивы. Функция preg_replace() перебирает элементы обоих массивов ивыполняет замену по мере их нахождения.

preg_split( )

Функция preg_split( ) аналогична split( ) за одним исключением -параметр шаблон может содержать регулярноевыражение. Синтаксис функции preg_split( ):

array preg_split (stringшаблон, string строка [, int порог [, int флаги]])

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

$user_info="+wj+++Gilmore+++++wjgi]more@hotmail.com

+++++++Columbus+++OH";

$fields = preg_split("/\+{1.}/", $user_info); 

while ($x <sizeof($fields)):

print $fields[$x]."<br>";

$x++;

endwhile;

Результат:

WJ

Gilmore

wjgilmore@hotmail.com

Columbus

OH

preg_grep( )

Функцияpreg_grep( ) перебирает все элементы заданногомассива и возвращает все элементы, вкоторых совпадает заданное регулярноевыражение. Синтаксис функции preg_grep():

array preg_grep (stringшаблон,array массив)

Примериспользования функции preg_grep( ) для поиска вмассиве слов, начинающихся на р:

$foods = array ("pasta","steak", "fish", "potatoes");

// Поискэлементов, начинающихся с символа "р".

// за которым следует один или несколькосимволов

$p_foods = preg_grep("/p(\w+)/", $foods):

$х = 0;

while ($x < sizeof($p_foods)):

print $p_foods[$x]."<br>";

$Х++;

endwhile;

Результат:

pasta

potatoes

Другиестроковые функции

Кромефункций для работы с регулярнымивыражениями, описанными в первой части этойглавы, в РНР существует более 70 функций длявыполнения практически всех мыслимыхопераций со строками. Подробноеперечисление и описание всех функцийвыходит за рамки этой книги и приведет кобычному повторению информации,приведенной в документации РНР. По этойпричине я превратил оставшуюся часть главыв своего рода список FAQ из вопросов, частовстречающихся во многих электронныхконференциях РНР и на многих сайтах этойтематики. На мой взгляд, этот способпозволяет гораздо эффективнее описатьобщие принципы громадной библиотекистроковых функций РНР.

Дополнение исжатие строк

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

chop ( )

Функцияchop( ) возвращает строку после удаления изнее завершающих пропусков и символов новойстроки. Синтаксис функции chop( ):

string chop(stringстрока)

В следующемпримере функция chop( ) удаляет лишние символыновой строки:

$header = "Tableof Contents\n\n";

$header = chop($header);

// $header = "Tableof Contents"

str_pad( )

Функция str_pad() выравнивает строку до определенной длинызаданными символами и возвращаетотформатированную строку. Синтаксисфункции str_pad( ):

string str_pad(string строка, int длина_дополнения [, string дополнение[, int тип_дополнения]])

Еслинеобязательный параметр дополнение неуказан, строка дополняется пробелами. Впротивном случае строка дополняетсязаданными символами. По умолчанию строкадополняется справа; тем не менее, вы можетепередать в параметре тип_дополненияконстанту STR_PAD_RIGHT, STR_PAD_LEFT или STR_PAD_BOTH, чтоприведет к дополнению строки в заданномнаправлении. Пример демонстрируетдополнение строки функцией str_pad( ) спараметрами по умолчанию:

$food = "salad";

print str_pad ($food,5): // Выводит строку "salad

В следующемпримере используются необязательныепараметры функции str_pad( ):

$header = "Tableof Contents";

print str_pad ($header, 5, "=+=+=", STR_PAD_BOTH);

// В браузере выводится строка =+=+= Таbе of Contents=+=+="

trim ( )

Функция trim( )удаляет псе пропуски с обоих краев строки ивозвращает полученную строку. Синтаксисфункции trim( ):

string trim (string страна]

К числуудаляемых пропусков относятся испециальные символы \n, \r, \t, \v и \0.

ltrim( )

Функция lrim( )удаляет все пропуски и специальные символыс левого края строки и возвращаетполученную строку. Синтаксис функции ltrim( ):

string ltrim(string строка)

Функцияудаляет те же специальные символы, что ифункция trim( ).

Определениедлины строки

Длину строкив символах можно определить при помощифункции strlen( ). Синтаксис .функции strlen( ):

int strlen(string строка)

Следующийпример демонстрирует определение длиныстроки функцией strlen( ):

$string = "hello";

$length = strlen($string);

// $length = 5

Сравнениедвух строк

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

  • strcmp( );
  • strcasecmp( );
  • strspn( );
  • strcspn( ).

Все этифункции подробно описаны в следующихразделах.

strcmp( )

Функция strcmp() сравнивает две строки с учетом регистрасимволов. Синтаксис функции strcmp():

int strcmp (string строка1,string строка2)

Послезавершения сравнения strcmp( ) возвращает одноиз трех возможных значений:

  • 0, еслистрока1 и строка2 совпадают;
  • < 0, еслистрока1 меньше, чем строка2;
  • > 0, еслистрока2 меньше, чем строка1.

В следующемфрагменте сравниваются две одинаковыестроки:

$sthng1 = "butter";

$string2 = "butter";

if ((strcmp($string1.$string2)) == 0) :

print "Strings areequivalent!"; endif;

// Команда if возвращает TRUE

strcasecmp( )

Функцияstrcasecmp( ) работает точно так же, как strcmp( ), заодним исключением - регистр символов присравнении не учитывается. Синтаксисфункции strcasecmp( ):

int strcasecmp (string cтpoкa1,string строка2)

В следующемфрагменте сравниваются две одинаковыестроки:

$string1 = "butter";

$string2 = "Butter";

if ((strcmp($string1,$string2)) == 0) :

print "Strings areequivalent!";

endif;

// Команда if возвращает TRUE

strspn( )

Функция strspn() возвращает длину первого сегмента строки1,содержащего символы, присутствующие встроке2. Синтаксис функции strspn( ):

int strspn(string строка1,string строка2)

Следующийфрагмент показывает, как функция strspn( )используется для проверки пароля:

$password ="12345";

if (strspn($password,"1234567890") != strlen($password)) :

print "Passwordcannot consist solely of numbers!";

endif:

strcspn( )

Функцияstrcspn( ) возвращает длину первого сегментастроки1, содержащего символы, отсутствующиев строке2. Синтаксисфункции strcspn( ):

int strcspn (string строка1,string строка2)

В следующемфрагменте функция strcspn( ) используется дляпроверки пароля:

$password ="12345";

if (strcspn($password,"1234567890") == 0) :

print "Passwordcannot consist solely of numbers!";

endif;

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

Приобработке больших объемов информациифункции регулярных выражений сильнозамедляют выполнение программы. Этифункции следует применять лишь приобработке относительно сложных строк, вкоторых регулярные выражениядействительно необходимы. Если же анализтекста выполняется по относительно простымправилам, можно воспользоватьсястандартными функциями РНР, которыезаметно ускоряют обработку. Все эти функцииописаны ниже.

strtok( )

Функция strtok() разбивает строку на лексемы поразделителям, заданным вторым параметром.Синтаксис функции strtok( ):

string strtok (string строка,string разделители)

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

$info = "WJGi1more:wjgilmore@hotmail.com | Columbus, Ohio";

//Ограничители - двоеточие (:), вертикальнаячерта (|) и запятая (.) $tokens = ":|,";

$tokenized = strtok($info,$tokens);

// Вывести элементы массива $tokenized

while ($tokenized):

echo "Element =$tokenized<br>";

// Обратитевнимание: при последующих вызовах strtok

// первыйаргумент не передается

$tokenized = strtok($tokens);

endwhile;

Результат:

Element = WJGilmore

Element =wjgilmore@hotmail.com

Element = Columbus

Element = Ohio

parse_str( )

Функцияparse_str( ) выделяет в строке пары <переменная-значение>и присваивает значения переменных втекущей области видимости. Синтаксисфункции parse_str( ):

void parse_str(string строка)

Функцияparse_str( ) особенно удобна при обработке URL,содержащих данные форм HTML или другуюрасширенную информацию. В следующемпримере анализируется информация,переданная через URL. Строка представляетсобой стандартныйспособ передачи данных между страницамилибо откомпилированных в гиперссылке, либовведенных в форму HTML:

$url = "fname=wj&lname=gilmore&zip=43210";

parse_str($url);

// Послевыполнения parse_str( ) доступны следующиепеременные:

// $fname = "wj":

// $lname = "gilmore";

// $zip ="43210"

Посколькуэта функция создавалась для работы с URL, онаигнорирует символ амперсанд (&).

Работас формами HTML в РНР описана в главе 10.

 

explode ( )

Функция explode() делит строку на элементы и возвращает этиэлементы в виде массива.Синтаксис функции explode( ):

array explode (string разделитель, string строка[, int порог])

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

$info = "wilson |baseball | indians";

$user = explode("|",$info);

// $user[0] ="wilson";

// $user[1] = "baseball";

// $user[2] = "Indians";

Функцияexplode( ) практически идентична функциирегулярных выражений POSIX split( ), описаннойвыше. Главное различие заключается в том,что передача регулярных выражений впараметрах допускается только при вызовеsplit( ).

implode ( )

Если функцияexplode( ) разделяет строку на элементы массива,то ее двойник - функция implode( ) - объединяетмассив в строку. Синтаксис функции implode( ):

string implode(string разделитель,array фрагменты)

Формированиестроки из массива продемонстрировано вследующем примере:

$ohio_cities = array("Columbus", "Youngstown", "Cleveland", "Cincinnati");

$city_string = implode("l",$ohio_cities);

// $city_string ="Columbus | Youngstown | Cleveland | Cincinnati";

Уimplode( ) имеется псевдоним - функция join( ).

 strpos ( )

Функция strpos() находит в строке первый экземплярзаданной подстроки. Синтаксис функции strpos():

int strpos(string строка, stringподстрока [, int смещение])

Необязательныйпараметр offset задает позицию, с которойдолжен начинаться поиск. Если подстрока ненайдена, strpos( ) возвращает FALSE (0).

В следующемпримере определяется позиция первоговхождения даты в файл журнала:

$log = "

206.169.23.11:/www/:2000-08-10

206.169.23.11:/www/logs/:2000-02-04

206.169.23.11:/www/img/:1999-01-31";

// В какойпозиции в журнале впервые встречается 1999год?

$pos = strpos($log,"1999");

// $pos = 95.поскольку первый экземпляр "1999"

// находитсяв позиции 95 строки, содержащейся впеременной $log

strrpos( )

Функция strrpos() находит в строке последний экземплярзаданного символа. Синтаксис функции strrpos( ):

int strpos(string строка,char символ)

Повозможностям эта функция уступает своемудвойнику - функции strpos( ), поскольку онапозволяет искать только отдельный символ, ане всю строку. Если во втором параметре strrpos() передается строка, при поиске будетиспользован только ее первый символ.

str_replace( )

Функцияstr_replace( ) ищет в строке все вхождениязаданной подстроки и заменяет их новойподстрокой. Синтаксис функции str_replace( ):

string str_replace(string подстрока,string замена, string строка)

Функцияsubstr_replace( ), описанная ниже в этом разделе,позволяет провести заме ну лишь вопределенной части строки. Ниже показано,как функция str_replace( ) используется дляпроведения глобальной замены в строке.

Еслиподстрока ни разу не встречается в строке,исходная строка не изменяется:

$favorite_food = "Myfavorite foods are ice cream and chicken wings";

$favorite_food =str_replace("chicken_wings", "pizza", $favohte_food);

//$favorite_food = "My favorite foods are ice cream and pizza"

strstr( )

Функция strstr() возвращает часть строки, начинающуюся спервого вхождения заданной подстроки.Синтаксис функции strstr( ):

string strstr(string строка,string подстрока)

В следующемпримере функция strstr( ) используется длявыделения имени домена из URL:

$url = "http://www.apress.com";$domain - strstr($url, ".");

// $domain = ".apress.com"

substr( )

Функцияsubstr( ) возвращает часть строки, начинающуюсяс заданной начальной позиции и имеющуюзаданную длину. Синтаксис функции substr( ):

string substr(string строка, intначало [, int длина])

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

  • еслипараметр начало положителен, возвращаемаяподстрока начинается с позиции строки сзаданным номером;
  • еслипараметр начало отрицателен, возвращаемаяподстрока начинается с позиции (длинастроки - начало);
  • еслипараметр длина положителен, в возвращаемуюподстроку включаются все символы отпозиции начало до позиции начало+длина.Если последняя величина превышает длинустроки, возвращаются символы до концастроки;
  • еслипараметр длина отрицателен, возвращаемаяподстрока заканчивается на заданномрасстоянии от конца строки.

Помнитео том, что параметр начало определяетсмещение от первого символа строки; такимобразом, возвращаемая строка вдействительности начинается с символа сномером (начало + 1).

Следующийпример демонстрирует выделение частистроки функцией substr( ):

$car = "1944 Ford";Smodel = substr($car, 6);

// Smodel = "Ford"

Пример сположительным параметром длина:

$car = "1944 Ford";

$model = substr($car,0, 4);

// $model ="1944"

Пример сотрицательным параметром длина:

$car = "1944 Ford";

$model = substr($car,2, -5);

// $model ="44"

 substr_count( )

Функцияsubstr_count( ) возвращает количество вхожденийподстроки в заданную строку. Синтаксисфункции substr_count( ):

int substr_count(string строка,string подстрока)

В следующемпримере функция substr_count( ) подсчитываетколичество вхождений подстроки ain:

$tng_twist = "Therain falls mainly on the plains of Spain";

$count = substr_count($tng_twist,"ain");

// $count = 4

substr_replace( )

Функцияsubstr_replace( ) заменяет часть строки, котораяначинается с заданной позиции. Если заданнеобязательный параметр длина, заменяетсяфрагмент заданной длины; в противном случаепроизводится замена по всей длинезаменяющей строки. Синтаксис функцииsubstr_replace( ):

string substr_replace(string строка, string замена,int начало [, int длина])

Параметрыначало и длина задаются по определеннымправилам:

  • еслипараметр начало положителен, заменаначинается с заданной позиции;
  • еслипараметр начало отрицателен, заменаначинается с позиции (длина строки -начало);
  • еслипараметр длина положителен, заменяетсяфрагмент заданной длины;
  • еслипараметр длина отрицателен, заменазавершается в позиции (длина строки -длина).

Простаязамена текста функцией substr_replace( )продемонстрирована в следующем примере:

$favs = " 'sfavorite links";

$name = "Alessia";

// Параметры"0, 0" означают, что заменяемый фрагментначинается

// изавершается в первой позиции строки.

$favs - substr_replace($favs,$name, 0, 0);

print $favs:

Результат:

Alessia's favoritelinks

Преобразованиестрок и файлов к формату HTML и наоборот

Преобразоватьстроку или целый файл к формату,подходящему для просмотра в web-браузере (илинаоборот), проще, чем может показаться напервый взгляд. В РНР для этого существуютспециальные функции.

Преобразованиетекста в HTML

Быстроепреобразование простого текста к форматуweb-браузера - весьма распространеннаязадача. В ее решении вам помогут функции,описанные в этом разделе.

nl2br( )

Функция nl2br( )заменяет все символы новой строки (\n)эквивалентными конструкциями HTML <br>.

Синтаксисфункции nl2br( ):

string nl2br(string строка)

Символыновой строки могут быть как видимыми (тоесть явно включенными в строку), так иневидимыми (например, введенными вредакторе). В следующем примере текстоваястрока преобразуется в формат HTMLпосредством замены символов \n разрывамистрок:

// Текстоваястрока, отображаемая в редакторе.

$text_recipe = "

Party Sauce recipe:

1 can stewed tomatoes

3 tablespoons freshlemon juice

Stir together, servercold.";

//Преобразовать символы новой строки в <br>

$htinl_recipe = nl2br($text_recipe)

Припоследующем выводе $html_recipe браузеру будетпередан следующий текст в формате HTML:

Party Sauce recipe:<br>

1 can stewed tomatoes<br>

3 tablespoons freshlemon juice<br>

Stir together, servercold.<br>

htmlentities( )

Функцияhtmlentities( ) преобразует символы вэквивалентные конструкции HTML. Синтаксисфункции htmlentities:

string htmlentities(string строка)

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

$user_input = "Thecookbook, entitled Cafe Francaise' costs < $42.25.";

$converted_input =htmlentities($user_input);

// $converted_input ="The cookbook, entitled 'Caf&egrave;

// Frac&ccediliaise'costs &lt; 42.25.";

Функция htmlentities( ) внастоящее время работает только длясимволов кодировки ISO-8559-1 (ISO-Latin-1). Крометого, она не преобразует пробелы в &nbsp;,как следовало бы ожидать.

htmlspecialchars( )

Функцияhtmlspecialchars( ) заменяет некоторые символы,имеющие особый смысл в контексте HTML,эквивалентными конструкциями HTML. Синтаксисфункции htmlspecialchars( ):

string htmlspecialchars(string строка)

Функция htmlspecial chars( ) в настоящее время преобразуетследующие символы:

&преобразуется в &amp;; " "преобразуется в &quot;;

<преобразуется в &lt;; > преобразуется в&gt;.

В частности,эта функция позволяет предотвратить вводпользователями разметки HTML в интерактивныхweb-приложениях (например, в электронныхфорумах). Ошибки, допущенные в разметке HTML,могут привести к тому, что вся страницабудет формироваться неправильно. Впрочем, уэтой задачи существует и более эффективноерешение - полностью удалить теги из строкифункцией strip_tags( ).

Следующийпример демонстрирует удалениепотенциально опасных символов функциейhtmlspeclalchars( ):

$user_input = "Ijust can't get of PHP & those fabulous cooking recipes!";

$conv_input =htmlspecialchars($user_input);

// $conv_input = "Ijust can't &lt;&lt;enough&gt;&gt; of PHP &amp those fabulouscooking

recipes!"

Еслифункция htmlspecialchars( ) используется всочетании с nl2br( ), то последнюю следуетвызывать после htmlspecialchars(). В противном случае конструкции <br>,сгенерированные при вызове nl2br( ),преобразуются в видимые символы.

get_html_translation_table( )

Функцияget_html_translation_table( ) обеспечивает удобныесредства преобразования текста вэквиваленты HTML Синтаксис функцииget_htrril_translation_table( ):

string get_html_translation_table(int таблица)

Функцияget_html_translation_table( ) возвращает одну из двухтаблиц преобразования (определяетсяпараметром таблица), используемых в работестандартных функций htmlspecialchars( ) и htmlentities( ).Возвращаемое значение можетиспользоваться в сочетании с другойстандартной функцией, strtr( ) (см. далее), дляпреобразования текста в код HTML.

Параметртаблица принимает одно из двух значений:

  • HTML_ENTITIES;
  • HTML_SPECIALCHARS.

В следующемпримере функция get_html_translation_table( )используется при преобразовании текста вкод HTML:

$string = "Lapasta e il piatto piu amato in Italia";

$translate =get_html_translation_table(HTML_ENTITIES);

print strtr($string, $translate);

//Специальные символы преобразуются вконструкции HTML

// и правильно отображаются вбраузере.

Кстати,функция array_flip( ) позволяет провестипреобразование текста в HTML в обратномнаправлении и восстановить исходный текст.Предположим, что вместо вывода результатаstrtr( ) в предыдущем примере мы присвоили егопеременной $translated string.

В следующемпримере исходный текст восстанавливаетсяфункцией array_flip( ):

$translate = array_flip($translate);

$translated_string -"La pasta &eacute; il piatto pi&uacute; amato in Italia";

$original_string = strtr($translated_string,$translate);

// $original_string ="La pasta e il piatto piu amato in Italia";

strtr( )

Функция strtr( )транслирует строку, то есть заменяет в нейвсе символы, входящие в строку источник,соответствующими символами строкиприемник. Синтаксис функции strtr( ):

string strtr(string строка,string источник, string приемник)

Если строкиисточник и приемник имеют разную длину,длинная строка усекается до размеровкороткой строки.

Существуетальтернативный синтаксис вызова strtr( ) сдвумя параметрами; в этом случае второйпараметр содержит ассоциативный массив,ключи которого соответствуют заменяемымподстрокам, а значения - заменяющимподстрокам. В следующем примере теги HTMLзаменяются XML-подобными конструкциями:

$source = array("<title>"=> "<h1>". "</title> =>"</h1>");

$string ="<h1>Today In PHP-Powered News"</h1>";

print strtr($string,$source);

// Выводитсястрока "<title>Today in PHP-Powered News</title>"

ПреобразованиеHTML в простой текст

Иногдавозникает необходимость преобразоватьфайл в формате HTML в простой текст. Функции,описанные ниже, помогут вам в решении этойзадачи.

strip_tags( )

Функцияstrip_tags( ) удаляет из строки все теги HTML и РНР,оставляя в ней только текст. Синтаксисфункции strip_tags( ):

string strip_tags(string строка [, string разрешенные_тerи])

Необязательныйпараметр разрешенные_теги позволяетуказать теги, которые должны пропускаться впроцессе удаления.

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

$user_input = "Ijust <b>love</b> РНР and <i>gourment</i> recipes!";

$stripped_input =strip_tags($user_input);

// $stripped_input ="I just love PHP and gourmet recipes!";

В следующемпримере удаляются не все, а лишь некоторыетеги:

$input = "I <b>love</b>to <a href = \"http://www.eating.com\">eat!</a>!";

$strip_input =strip_tags ($user_input, "<a>");

// $strip_input ="I love to <a href = \"http://www.eating.com\">eat!</a>!";

Удаление тегов из текстатакже производится функцией fgetss( ),описанной в главе 7.

 get_meta_tags( )

Хотя функцияget_meta_tags( ) и не имеет прямого отношения кпреобразованию текста, зто весьма полезнаяфункция, о которой следует упомянуть.Синтаксис функции get_meta_tags( ):

array get_meta_tags(string имя_файла/URL [, int включение_пути])

Функцияget_meta_tags( ) предназначена для поиска в файлеHTML тегов МЕТА.

Теги МЕТАсодержат информацию о странице,используемую главным образом поисковымисистемами. Эти теги находятся внутри парытегов <head>...</head>. Применение теговМЕТА продемонстрировано в следующемфрагменте (назовем его example.html, поскольку онбудет использоваться в листинге 8.2):

<html>

<head>

<title>PHPRecipes</title>

<meta name="keywords"content="gourmet. PHP, food. code, recipes, chef, programming, web">

<meta name="description"content="PHP Recipes provides savvy readers with the latest in PHP

programming and gourmetcuisine!">

<meta name="author"content="WJ Gilmore">

</head>

Функцияget_meta_tags( ) ищет в заголовке документа теги,начинающиеся словом МЕТА, и сохраняет именатегов и их содержимое в ассоциативноммассиве. В листинге 8.2 продемонстрированоприменение этой функции к файлу example.html.

Листинг8.2. Извлечениетегов МЕТА из файла HTML функцией get_meta_tags( )

$meta_tags =get_meta_tags("example.html"):

// Переменная$meta_tags содержит массив со следующейинформацией:

// $meta_tags["keywords"]= "gourmet. PHP. food. code, recipes, chef, programming. Web":

// $meta_tags["description"]= "PHP Recipes provides savvy readers with the latest in PHP

programming and gourmetcuisine";

// $meta_tags["author"]= "WJ Gilmore";

Интереснаяподробность: данные тегов МЕТА можноизвлекать не только из файлов, находящихсяна сервере, но и из других URL.

ТегиМЕТА и их использование превосходноописаны в статье Джо Берна (Joe Burn) на сайте HTML Goodies: http://htmlgoodies.earthweb.com/tutors/meta.html.

Преобразованиестроки к верхнему и нижнему регистру

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

  • strtolower( );
  • strtoupper( );
  • ucfirst( );
  • ucwords( ).

Все этифункции подробно описаны ниже.

strtolower( )

Функцияstrtolower( ) преобразует все алфавитные символыстроки к нижнему регистру. Синтаксисфункции strtolower( ):

string strtolower(stringстрока)

Неалфавитныесимволы функцией не изменяются.Преобразование строки к нижнему региструфункцией strtolower( ) продемонстрировано вследующем примере:

$sentence = "COOKINGand PROGRAMMING PHP are my TWO favorite pastimes!";

$sentence = strtolower($sentence);

// Послевызова функции $sentence содержит строку

// "cooking andprogramming php are my two favorite pastimes!"

strtoupper( )

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

string strtoupper(string строка)

Неалфавитныесимволы функцией не изменяются.Преобразование строки к верхнему региструфункцией strtoupper( ) продемонстрировано вследующем примере:

$sentence = "cookingand programming PHP are my two favorite pastimes!";

$sentence = strtoupper($sentence);

// Послевызова функции $sentence содержит строку

// "COOKING ANDPROGRAMMING PHP ARE MY TWO FAVORITE PASTIMES!"

ucfirst( )

Функция ucfirst() преобразует к верхнему регистру первыйсимвол строки - при условии, что онявляется алфавитным символом. Синтаксисфункции ucfirst( ):

string ucfirst(string строка)

Неалфавитныесимволы функцией не изменяются.Преобразование первого символа строкифункцией ucfirst( ) продемонстрировано вследующем примере:

&sentence = "cookingand programming PHP are my two favorite pastimes!";

$sentence = ucfirst($sentence);

// Послевызова функции $sentence содержит строку

// "Cooking andprogramming PHP are mу two favorite pastimes!"

ucwords( )

Функция ucwords() преобразует к верхнему регистру первуюбукву каждого слова в строке. Синтаксисфункции ucwords( ):

string ucwords(string строка")

Неалфавитныесимволы функцией не изменяются. <Слово>определяется как последовательностьсимволов, отделенная от других элементовстроки пробелами. В следующем примерепродемонстрировано преобразование первыхсимволов слов функцией ucwords( ):

$sentence = "cookingand programming PHP are my two favorite pastimes!";

$sentence = ucwords($sentence);

// Послевызова функции $sentence содержит строку

// "Cooking AndProgramming PHP Are My Two Favorite Pastimes!"

Проект:идентификация браузера

Каждыйпрограммист, пытающийся создать удобный web-сайт,должен учитывать различия в форматированиистраниц при просмотре сайта в разныхбраузерах и операционных системах. Хотяконсорциум W3 (http://www.w3.org) продолжаетпубликовать стандарты, которых должныпридерживаться программисты при созданииweb-приложений, разработчики браузеров любятдополнять эти стандарты своими маленькими<усовершенствованиями>, что в конечномсчете вызывает хаос и путаницу.Разработчики часто решают эту проблему,создавая разные страницы для каждого типабраузера и операционной системы - при этомобъем работы значительно увеличивается, нозато итоговый сайт идеально подходит длялюбого пользователя. Результат - хорошаярепутация сайта и уверенность в том, чтопользователь посетит его снова.

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

Приведенныйниже проект (sniffer.php) показывает, какиспользовать функции РНР для работы срегулярными выражениям с целью полученияинформации по запросам. Программаопределяет тип и версию браузера иоперационной системы, после чего выводитполученную информацию в окне браузера. Нопрежде чем переходить к непосредственномуанализу программы, я хочу представить одиниз главных ее компонентов - стандартнуюпеременную РНР $HTTP_USER_AGENT. В этой переменнойв строковом формате хранятся различныесведения о браузере и операционной системепользователя - именно то, что насинтересует. Эту информацию можно легковывести на экран всего одной командой:

<?

echo $HTTP USER_AGENT;

?>

При работе вInternet Explorer 5.0 на компьютере с Windows 98 результатбудет выглядеть так:

Mozilla/4.0 (compatible;MSIE 5.0; Windows 98; DigExt)

Для NetscapeNavigator 4.75 выводятся следующие данные:

Mozilla/4.75 (Win98; U)

Sniffer.phpизвлекает необходимые данные из $HTTP_USER_AGENTпри помощи функций обработки строк ирегулярных выражений. Алгоритм программына псевдокоде:

  • Определитьдве функции для идентификации браузера иоперационной системы: browser_info( ) и opsys_info( ).Начнем с псевдокода функции browser_info( ).
  • Определитьтип браузера, используя функцию егед( ). Хотяэта функция работает медленнее упрощенныхстроковых функций типа strstr( ), в данномслучае она удобнее, поскольку регулярноевыражение позволяет определить версиюбраузера.
  • Воспользоватьсяконструкцией if/elseif для идентификацииследующих браузеров и их версий: Internet Explorer,Opera, Netscape и браузер неизвестного типа.
  • Вернутьинформацию о типе и версии браузера в видемассива.
  • Функцияopsys_info( ) определяет тип операционнойсистемы. На этот раз используется функцияstrstr( ), поскольку тип ОС определяется и безприменения регулярных выражений.
  • Воспользоватьсяконструкцией if/elseif для идентификацииследующих систем: Windows, Linux, UNIX, Macintosh инеизвестная операционная система.
  • Вернутьинформацию об операционной системе.

Листинг8.3. Идентификациятипа браузера и операционной системыклиента

<?

/*

Файл : sniffer.php

Назначение:Идентификация типа/версии браузера иплатформы

Автор: В. Дж.Гилмор

Дата : 24августа 2000 г.

*/

// Функция:browser_info

// Назначение:Возвращает тип и версию браузера

function browser_info ($agent){

// Определить тип браузера

// Искатьсигнатуру Internet Explorer

if (ereg('MSIE ([0-9].[0-9]{1,2})',$agent, $version))

$browse_type = "IE";

$browse version = $version[1];

// Искатьсигнатуру Opera

elseif (ereg( 'Opera([0-9].[0-9]{1,2})'. $agent, $version)):

$browse_type = "Opera":

$browse_version = $version[1]:

// Искатьсигнатуру Netscape. Проверка браузера Netscape

// *должна*выполняться после проверки Internet Explorer и Opera,

// посколькувсе эти браузеры любят сообщать имя

// Mozilla вместес настоящим именем.

elseif (ereg( 'Mozilla/([0-9].[0-9]{1,2})'.$agent, $version)) :

$browse_type = "Netscape";

$browse_version = $version[1];

// Если это неInternet Explorer, Opera или Netscape.

// значит, мыобнаружили неизвестный браузер,

else :

$browse_type = "Unknown";

$browse_version = "Unknown";

endif:

// Вернутьтип и версию браузера в виде массива

return array($browse_type, $browse_version);

} // Конецфункции browser_info

// Функция:opsys_info

// Назначение:Возвращает информацию об операционнойсистеме пользователя

function opsys_info($agent){

//Идентифицировать операционную систему

//Искать сигнатуру Windows

if ( strstr ($agent. 'win') ) :

$opsys ="windows";

// Искатьсигнатуру Linux

elseif ( strstr($agent, 'Linux') ) :

$opsys = "Linux";

// Искатьсигнатуру UNIX

elseif ( strstr (Sagent, 'Unix') ) :

$opsys = "Unix";

// Искатьсигнатуру Macintosh

elseif ( strstr ($agent, 'Mac') ) :

$opsys = "Macintosh";

//Неизвестная платформа else :

$opsys = "Unknown";

endif;

// Вернутьинформацию об операционной системе

return $opsys;

} // Конецфункции opsys_info

// Сохранитьвозвращаемый массив в списке

list ($browse_type.$browse_version) = browser_info ($HTTP_USER_AGENT); Soperating_sys = opsysjnfo ($HTTP_USER_AGENT);

print "BrowserType: $browse_type <br>";

print "BrowserVersion: $browse_version <br>";

print "OperatingSystem: $operating_sys <br>":

?>

Вот и все!Например, если пользователь работает вбраузере Netscape 4.75 на компьютере с системойWindows, будет выведен следующий результат:

Browser Type: Netscape

Browser Version: 4.75

Operating System: Windows

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

Итоги

В этой главебыл изложен довольно обширный материал.Какой прок от языка программирования, еслив нем нельзя работать с текстом? Мырассмотрели следующие темы:

  • общиесведения о регулярных выражениях встилях POSIX и Perl;
  • стандартныефункции РНР для работы с регулярнымивыражениями;
  • изменениедлины строки;
  • определениедлины строки;
  • альтернативныефункции РНР для обработки строковойинформации;
  • преобразованиепростого текста в HTML и наоборот;
  • изменениерегистра символов в строках.

Следующаяглава открывает вторую часть книги -кстати, мою любимую. В ней мы начнемзнакомиться со средствами РНР,ориентированными на Web, рассмотрим процессдинамического создания содержимого,включение файлов и построение общихшаблонов. В дальнейших главах части 2рассматриваются работа с формами HTML, базыданных, отслеживание данных сеанса инетривиальные средства работы с шаблонами.Держитесь - начинается самое интересное!