Главное меню

Манипулирование строками и регулярные выражения

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

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

В этой главе рассматриваются следующие темы.

• Форматирование строк.

• Объединение и разбиение строк.

• Сравнение строк.

• Сопоставление и замена подстрок с помощью функций обработки строк.

• Использование регулярных выражений.

Пример приложения: интеллектуальная форма отправки электронной почты

В этой главе строковые функции и функции регулярных выражений рассматриваются в контексте приложения интеллектуальной формы отправки электронной почты (Smart Form Mail). Написанные в этой главе сценарии будут добавлены к сайту компании "Автозапчасти от Вована", который разрабатывается уже на протяжении нескольких глав.

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

Манипулирование строками

Вместо того чтобы отправлять форму по обобщенному адресу электронной почты наподобие feedback@example. com, мы постараемся сделать этот процесс более интеллектуальным за счет поиска во вводимых данных ключевых слов и выражений и последующей отправки сообщения электронной почты соответствующему сотруднику компании "Автозапчасти от Вована". Например, если сообщение электронной почты содержит слово "advertising" (“реклама”), данные обратной связи будут направлены в отдел маркетинга. Если сообщение электронной почты поступает от самого крупного клиента Вована, оно, по идее, должно быть направлено непосредственно ему как руководителю.

Мы начнем рассмотрение с простого сценария, показанного в листинге 4.1, дополняя его по мере изучения материала.

Манипулирование строками

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

В этом сценарии мы осуществляем конкатенацию полей формы и при помощи РНР-функции mail () и отправляем их по электронной почте по адресу feedback@example. com. До сих пор функция mail () еще не использовалась, поэтому сейчас мы рассмотрим, как она работает.

Совершенно очевидно, что эта функция отправляет сообщение электронной почты. Ее прототип имеет следующий вид:

bool mail(string кому, string тема, string сообщение [,

string дополнительные_заголовки [, string дополнительные_параметры] ]) ;

Первые три параметра являются обязательными и представляют, соответственно, адрес, по которому должно быть отправлено сообщение, строку темы и содержимое сообщения. Четвертый параметр может применяться для отправки любых дополнительных допустимых заголовков сообщения электронной почты. В данном примере четвертый параметр используется для включения в сообщение адреса "From:" (“От:”) для указания отправителя. Его можно также применять для добавления таких полей, как "Reply-To:" (“Ответить:”) и "Сс:" (“Копия”). Если вам необходимо ввести более одного дополнительного заголовка, их нужно просто разделить символами новой строки (\n\r), как показано в следующем примере:

$additional_headers= "From: webserver@example. com\n\r"

."Reply-То: bob@example. com";

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

Чтобы можно было пользоваться функцией mail (), при настройке РНР потребуется указать применяемую программу передачи электронной почты. Если в представленном виде сценарий не работает, то, видимо, допущена ошибка при инсталляции PHP и MySQL.

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

Форматирование строк

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

Усечение строки: функции chop (), ltrim () и trim ()

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

Для упомянутой цели в РНР предусмотрены три полезных функции. В начале сценария – там, где входным переменным формы назначаются короткие имена – можно использовать функцию trim () для приведения вводимых данных в порядок:

$name = trim ($_POST ['name']) ;

$email = trim($_POST['email']);

$feedback = trim($_POST['feedback']);

Функция trim () удаляет пробельные символы в начале и конце строки и возвращает результирующую строку. При этом по умолчанию удаляются символы новой строки (\n), возврата каретки (\r), символы горизонтальной (\t) и вертикальной (\х0В) табуляций, конца строки (\0) и обычные пробелы. Вы можете также указать второй параметр, который содержит список символов, подлежащих удалению из строки, вместо стандартного списка. В зависимости от обстоятельств вместо этой функции можно использовать ltrim() или rtrim(). Обе они аналогичны функции trim() в том, что принимают редактируемую строку в качестве параметра и возвращают отформатированную строку. Различие между ними состоит в том, что функция trim () удаляет пробельные символы в начале и конце строки, ltrim() удаляет их только в начале строки (слева), a rtrim() – только в конце строки (справа).

Форматирование строк для отображения

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

Использование HTML-форматирования: функция nl2br ()

Функция nl2br() принимает строку в качестве параметра и заменяет в ней все символы новой строки XHTML-дескриптором <br />. Данная возможность полезна при выводе длинной строки в окне браузера. Например, можно воспользоваться этой функцией для форматирования отзыва клиента при его выводе на экран:

<р>Ваш отзыв (приведенный ниже) отправлен.</р>

<P><?php echo nl2br($mailcontent) ; ?> </p>

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

Форматирование строк для целей печати

До сих пор для вывода строк в окне браузера мы использовали языковую конструкцию echo. РНР поддерживает также конструкцию print (), которая выполняет ту же операцию, что и echo, при этом возвращает значение true или false, в зависимости от того, успешно ли она была выполнена.

Форматирование строк

Обе эти конструкции выводят строку "как она есть". С помощью функций printf () и sprintf () можно выполнять более сложное форматирование. Фактически эти функции реализуют одни и те же действия, однако printf () выводит отформатированную строку в окне браузера, a sprintf () только возвращает сформатированную строку.

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

Прототипы этих функций имеют следующий вид:

string sprintf (string формат [, mixed аргументы ...])

void printf (string формат [, mixed аргументы ...])

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

Например, в операторе echo можно указывать переменные, которые должны быть выведены, например, так:

echo "Общая сумма заказа: $total.";

Для получения того же результата с помощью функции printf () применяется следующая конструкция:

printf ("Общая сумма заказа: %s.", $total);

Последовательность символов %s в строке формата называется спецификацией преобразования. Указанная спецификация означает "заменить строкой". В рассматриваемом случае она будет заменена значением переменной $ total, которое интерпретируется как строка.

Если бы значением, хранящимся в переменной $total, было 12.4, в обоих этих случаях выводилось бы 12.4.

Преимущество применения функции printf () состоит в том, что в этом случае можно использовать более удобную спецификацию преобразования, чтобы указать, что на самом деле переменная $total является числом с плавающей точкой и что оно должно содержать два знака после десятичной точки, как показано в следующем примере:

printf ("Общая сумма заказа: %.2f", $total);

С учетом заданного форматирования и значения 12.4 переменной $total, на экран будет выведено 12.40.

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

printf ("Общая сумма заказа: %.2f (с доставкой: %.2f) ", $total, $total_shipping);

В рассматриваемом случае первая спецификация преобразования применяется к переменной $total, а вторая – к переменной $total_shipping.

Все спецификации преобразования имеют одинаковый формат:

% [' дополняющий_символ] [-] [ширина] [. точность] тип

Все спецификации преобразования начинаются с символа %. Если вы хотите вывести символ %, следует воспользоваться последовательностью %%.

Дополняющий_символ не относится к числу обязательных параметров. Он будет использоваться для дополнения переменной до указанной ширины. Примером может служить добавление ведущих нулей к такому числу, как значение счетчика. Дополняющим символом по умолчанию является пробел. Если вы указываете пробел или 0, предварять его одинарной кавычкой () не нужно. Все остальные символы должны предваряться одинарной кавычкой.

Символ " - " является необязательным. Он указывает, что данные в поле будут выравниваться по левому краю, а не по правому, как определено по умолчанию.

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

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

Последним параметром спецификации является код типа. Краткое описание используемых кодов типа представлено в табл. 4.1.

Форматирование строк

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

printf ("Общая сумма заказа: %2\$.2f. (с доставкой: %1\$.2f) ", $total_shipping, $total);

Вполне достаточно внести позицию аргумента в список, следующий непосредственно за знаком %, после чего следует символ $ – в рассматриваемом нами примере последовательность 2\$ означает "заменить вторым аргументом списка". Этот метод может использоваться также и для повторяющихся аргументов.

Две альтернативных версии этих функций называются vprintf () и vsprintf (). Они принимают два параметра: строку формата и массив аргументов, а не переменное количество параметров.

Изменение регистра строки

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

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

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

Форматирование строк

Форматирование строк для хранения: функции addslashes () и stripslashes ()

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

Некоторые символы вполне могут быть частью строки, однако иногда они становятся источником проблем, в особенности при записи строки в базу данных, поскольку она может интерпретировать их как управляющие символы. Такими символами являются кавычки (одинарные и двойные), символы обратной косой черты (\) и символ NULL.

Нужно найти способ пометки, или литерализации, этих символов, чтобы такие СУБД, как MySQL, могли понять, что мы имеем в виду литеральное представление специального символа, а не его интерпретацию в качестве управляющей последовательности. Чтобы литерализоватъ эти символы, перед ними необходимо поместить символ обратной косой черты. Например, " (двойная кавычка) превращается в \", а \ (обратная косая черта) – в \\ (две обратных косых черты). (Это правило применяется к каждому специальному символу, поэтому при наличии в строке символов \\ их следует заменить последовательностью \\\\.)

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

$feedback = addslashes(trim($_POST['feedback']));

Подобно многим другим строковым функциям, addslashes() принимает строку в качестве параметра и возвращает переформатированную строку.

Результаты применения этих функций к строке можно видеть на рис. 4.3.

Форматирование строк

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

Если вы видите такой результат, значит, РНР сконфигурирован на автоматическое добавление и удаление слешей. Данная возможность носит название магических кавычек и управляется директивой конфигурации magic_quotes_gpc. Буквы "gpc" в имени директивы означают GET, POST и cookie. Это значит, что все переменные, поступающие из упомянутых источников, автоматически помещаются в кавычки. Проверить, включена ли директива magic_quotes_gpc, можно с помощью функции get_magic_quotes_gpc (), которая вернет значение true, если это так.

Форматирование строк

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

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

Объединение и разбиение строк с помощью строковых функций

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

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

Использование функций explode (), implode () и join ()

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

array explode (string разделитель, string исх_строка [, int лимит]);

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

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

$email_array = explode('@', $email);

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

if ($email_array[1] == "bigcustomer.com") {

$toaddress = "bob@example. com";

} else {

$toaddress = "feedback@example. com";

}

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

if (strlower($email_array[1]) == "bigcustomer.com") {

$toaddress = "bob@example. com";

} else {

$toaddress = "feedback@example. com";

}

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

$new_email = implode('@', $email_array);

Приведенный выше оператор принимает элементы из массива $email_array и объединяет их со строкой, переданной в первом параметре. Вызов этой функции подобен вызову explode (), но ее действие противоположно.

Использование функции strtok ()

В отличие от функции explode (), которая позволяет за один вызов делить на части сразу всю строку, функция strtok () ("string token" – "лексема строки") дает возможность получить фрагменты строки (называемые лексемами), по одному за вызов. Эта функцию следует рассматривать как полезную альтернативу функции explode () при поочередной обработке слов из строки.

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

srting strtok (string исх_строка, string разделитель);

В качестве параметра разделитель можно использовать символ или строку символов, однако следует иметь в виду, что строка ввода будет разделяться по каждому из символов разделителя, а не по всей строке разделителя (как имеет место в функции explode ()).

Вызов функции strtok () не столь прост, как может показаться, если судить только по ее прототипу. Для получения первой лексемы из строки нужно вызвать функцию strtok () со строкой, которую требуется разбить на лексемы, и с разделителем. Чтобы получить из заданной строки последующие лексемы, достаточно передать функции один параметр, а именно – разделитель. Функция сохраняет собственный внутренний указатель на позицию разделителя в строке. Если требуется переустановить указатель, необходимо снова передать строку в функцию.

Как правило, функция strtok () используется так, как показано ниже:

$token = strtok($feedback, " ");

echo $token."<br />";

while ($token!= " ") {

$token = strtok(" ");

echo $token."<br />";

}

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

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

Использование функции substr ()

Функция substr() ("substring" – "подстрока") позволяет получить доступ к подстроке между заданными начальной и конечной позициями в исходной строке. Для нашего примера она не подходит, однако может оказаться полезной, если требуется получить доступ к некоторым частям строк фиксированного формата.

Функция substr () имеет следующий прототип:

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

Эта функция возвращает подстроку из строки строка, начиная с позиции начало длиной длина.

Рассмотрим примеры использования показанной ниже тестовой строки:

$test = 'Вы прекрасно обслуживаете клиентов';

Если вы вызовете substr (), задав некоторое положительное число в качестве параметра начало (и ничего больше), вы получите строку, начиная с позиции начало и до конца строки. Например:

substr($test, 3);

возвращает строку прекрасно обслуживаете клиентов. Обратите внимание, что нумерация позиций строки начинается с 0, как в массивах.

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

substr($test, -8);

возвращает подстроку клиентов.

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

substr($test, 0, 2) ;

возвращает первые два символа строки, а именно, подстроку Вы.

Следующий код:

echo substr($test, 3, -9) ;

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

Сравнение строк

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

Упорядочение строк: функции strcmp(), strcasecmp() и strnatcmp()

Функции strcmp (), strcasecmp () и strnatcmp () служат для сравнения строк, которое может понадобиться при сортировке данных.

Прототип функции strcmp () ("string comparing" – "сравнение строк") имеет вид:

int strcmp(string str1, string str2);

Функция принимает две строки, которые и сравнивает. Если они равны, функция возвращает значение 0. Если в лексикографическом порядке строка str1 следует за строкой str2 (т.е. больше ее), функция strcmp () вернет число больше 0. Если строка str1 меньше строки str2, функция strcmp () вернет число меньше 0. Эта функция чувствительна к регистру.

Функция strcasecmp () идентична рассмотренной выше функции и отличается от нее только тем, что она к регистру не чувствительна.

Функция strnatcmp () ("string natural comparing" – "естественное сравнение строк") и ее нечувствительный к регистру эквивалент srtnatcasecmp () сравнивают строки в "естественном порядке", который более привычен для человека. Например, функция strcmp () располагает строку "2" после строки "12", поскольку лексикографически первая строка больше второй. Функция strnatcmp () расположила бы эти строки в обратном порядке.

Проверка длины строки с помощью функции strlen ()

Длину строки можно проверить с помощью функции strlen (). Если передать этой функции строку, она вернет ее длину. Например, оператор strlen ("привет") возвращает значение 6.

Эту функцию можно задействовать для проверки правильности вводимых данных. Рассмотрим пример с адресом электронной почты для создаваемой нами формы, который хранится в переменной $email. Один из основных способов проверки правильности адреса электронной почты, хранящегося в переменной $email, – это проверка его длины. По нашему мнению, минимальная длина адреса электронной почты составляет шесть символов. Например, если полный адрес содержит код страны без какого-либо домена второго уровня, однобуквенное имя домена и однобуквенный адрес электронной почты, он может иметь вид а@а.to. Следовательно, программа может генерировать сообщение об ошибке, если длина адреса оказывается меньше этого значения:

if (strlen($email) < 6) {

echo 'Недопустимый адрес электронной почты';

exit; // продолжение РНР-сценария

}

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

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

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

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

Имея в своем распоряжении рассмотренные выше функции, можно было бы воспользоваться функции explode () или strtok() для получения отдельных слов сообщения, а затем сравнить их, используя операцию == или функцию strcmp().

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

Поиск подстрок в строках: функции strstr(), strchr(), strrchr() и stristr()

Для поиска строки внутри другой строки можно использовать любую из функций strstr(), strchr(), strrchr() или stristr().

Функция strstr() ("string in string" – "поиск строки в строке") является наиболее общей и может использоваться для поиска строки или символа внутри более длинной строки. В РНР функция strchr() ("character in string" – "поиск символа в строке") полностью совпадает с функцией strstr(), хотя ее имя предполагает, что она применяется для поиска символа в строке, аналогично ее версии в языке С. В РНР любая из этих функций может применяться для поиска строки внутри строки, в том числе для поиска строки, состоящей только из одного символа.

Функция strstr() имеет следующий прототип:

string strstr(string heystack, string needle);

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

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

$toaddress = 'feddback@example. com'; // значение по умолчанию

// Изменить значение переменной $toaddress при наличии определенного слова

if (strstr ($feedback, 'магазин'))

$toaddress = 'retail@example. com';

else if (strstr($feedback, 'доставк'))

$toaddress = 'fulfillment@example. com';

else if (strstr($feedback, 'счет'))

$toaddress = 'accounts@example. com';

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

fulfillment@example. com

Существует две модификации функции strstr(). Первая модификация – это функция stristr(), которая практически идентична предыдущей функции, но не чувствительна к регистру. Это удобно в рассматриваемом приложении, поскольку клиент может вводить "доставк", "Доставк" или, скажем, "ДОСТАВК".

Второй вариант – функция strrchr(), которая также идентична функции strstr(), но с небольшим отличием: она возвращает часть строки heystack, начиная с последнего вхождения строки needle.

Определение позиции подстроки: функции strpos() и strrpos()

Функции strpos() и strrpos() действуют аналогично функции strstr() и отличаются от нее только тем, что вместо подстроки они возвращают числовую позицию строки needle внутри строки heystack. Любопытно, что в официальном руководстве по РНР рекомендуется применять strpos() вместо strstr() по причине ее высокой скорости.

Функция strpos() ("string position" – "позиция в строке") имеет следующий прототип:

string strpos(string heystack, string needle [, int offset]);

Возвращаемое целочисленное значение представляет собой первое вхождение строки needle внутри строки heystack. Как обычно, первый символ занимает нулевую позицию.

Например, следующий код выводит в окне браузера значение 4:

$test = "Приветствуем на нашем сайте!";

echo strpos($test, "е");

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

Необязательный параметр offset используется для указания позиции внутри строки heystack, с которой должен начинаться поиск. Например:

echo strpos($test, 'в', 4);

Этот код выведет в окне браузера значение 8, поскольку РНР начинает поиск символа "в" с четвертой позиции и, следовательно, не видит этот символ в третьей позиции (считая от нуля).

Функция strrpos() действует почти так же, отличие лишь в том, что она возвращает позицию последнего вхождения строки needle в строке heystack.

В любом из этих случаев, если needle не содержится в строке heystack, функции strpos() и strrpos() возвращают значение false. Это обстоятельство может стать источником проблем, поскольку в слабо типизированном языке, коим является РНР, значение false эквивалентно 0, т.е. первому символу в строке.

Вы можете избежать этих проблем, воспользовавшись операцией === для проверки возвращаемых значений:

$result = strpos ($test, "П");

if ($result === false) {

echo "He найдено"

} else {

echo "Найдено в позиции". $result;

}

Замена подстрок: функции str_replace() и substr_replace()

Функциональные возможности поиска и замены могут оказаться исключительно полезными при работе со строками. Поиск и замену можно использовать для персонализации документов, сгенерированных РНР, например, для замены <имя> именем конкретного лица, а <адрес> – его адресом. Эти функции можно использовать также для цензурирования определенных выражений, например, в приложении форума или даже в нашем приложении интеллектуальной формы отправки электронной почты. С этой целью опять можно воспользоваться строковыми функциями или функциями обработки регулярных выражений.

Чаще всего для замены применяется строковая функция str_replace() ("string replace" – "замена строки"). Она имеет следующий прототип:

mixed str_replace (mixed needle, mixed new_needle, mixed heystack [, int &count]);

Эта функция заменяет все экземпляры строки needle в строке heystack строкой new_needle и возвращает новую версию heystack.

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

Вы можете передавать все параметры как массивы, и функция str_replace() обработает их вполне осмысленно. Можно задать массив слов, подлежащих замене, а также массив слов, которыми, соответственно, будут заменены слова первого массива, и массив строк, к которому будут применяться эти правила. Данная функция вернет массив обновленных строк.

Например, поскольку некоторые клиенты могут использовать приложение интеллектуальной формы отправки электронной почты для выражения своего недовольства, они могут употребить грубые выражения. Будучи программистом, вы легко можете оградить персонал различных подразделений компании "Автозапчасти от Вована" от всякого рода оскорблений за счет использования массива $offcolor, который содержит слова подобного рода. Ниже показан пример вызова функции str_replace() с передачей ей такого массива.

$feedback = str_replace($offcolor, '%!@*', $feedback);

Функция substr_replace() ("substring replace" – "замена подстроки") используется для поиска и замены конкретной подстроки на основе ее позиции в строке. Она имеет следующий прототип:

string substr_replace(string string, string replacement, int start[, int length]);

Эта функция заменяет часть строки string строкой replacement. Какую именно часть – зависит от значений параметра start и от необязательного параметра length.

Значение параметра start представляет собой смещение, с которого начинается замена. Если оно является нулевым или положительным, смещение определяется относительно начала строки, если же оно отрицательно, то смещение определяется относительно конца строки. Например, приведенная ниже строка кода заменяет последний символ в переменной $test символом "ф":

$test = substr_replace ($test, 'ф', -1);

Параметр length является необязательным и задает позицию, в которой РНР прекращает замену. Если это значение не указано, замена производится с позиции, определенной параметром start, и до конца строки.

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