Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Обзор инструментов SEO-оптимизатора и методов продвижения" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
← Сентябрь 2005 → | ||||||
1
|
2
|
3
|
4
|
|||
---|---|---|---|---|---|---|
6
|
7
|
8
|
9
|
10
|
11
|
|
12
|
13
|
14
|
15
|
16
|
17
|
18
|
19
|
20
|
21
|
22
|
23
|
24
|
25
|
26
|
27
|
28
|
29
|
30
|
Статистика
0 за неделю
CGI-программирование с самого начала
Информационный Канал Subscribe.Ru |
Уважаемые подписчики!
В этом выпуске мы продолжаем тему работы со строками в языке Perl.
Напоминаем, что предыдущие выпуски можно прочитать здесь:
http://subscribe.ru/archive/inet.webbuild.perlcgi
Функции chop и chomp
При написании программ часто бывает нужно удалить символ в конце строки. В основном, это связано с тем, что при разбиении многострочного текста на строки (скажем, при построчном чтении текстового файла) Perl передает строку полностью, включая и символ конца строки (обычно - \n).
В этом случае для получения "текстовой части" строки нужно удалить ее последний символ, если это - разделитель.
Функция chop (переменная) удаляет последний символ строки; при этом она в качестве результата возвращает удаленный символ. Если в качестве переменной передается массив, то будет обработан каждый его элемент. Если передано имя хэша, то будут обработаны все его значения.
Функция chomp (переменная) тоже удаляет последний символ строки, но более "интеллектуально", и именно ее следует применять для удаления разделителей в концах строк. Эта функция удаляет последний символ только в том случае, если он совпадает со значением специальной переменной '$/', в противном случае ничего не удаляет. С массивами и хэшами ведет себя аналогично chop. Функция возвращает общее количество удаленных символов.
Перевод чисел из одной системы счисления в другую
Функции oct (строка) и hex (строка) воспринимают строку как число, записанное соответственно в 8-ричной или 16-ричной системе счисления и возвращают соответствующее число в "обычной" десятичной системе.
Работа с кодами символов
Как я уже говорил, строки являются удобным способом хранения не только текстовых обрабатываемых данных, но и любых других, т.к. строка может содержать последовательность любых байт.
При работе с бинарными данными, хранящимися в строке, часто бывает нужно получить код символа (собственно, байт, которым этот символ "представлен"), а также совершить обратную операцию - по коду символа получит символ, который затем можно "подставить" в строку в нужное место.
Самый простой вариант это сделать - воспользоваться соответственно функциями ord и chr.
Функция ord (строка) возвращает код первого символа строки.
Функция chr (число) возвращает символ, соответствующий коду <число>.
Более мощные средства для работы с бинарными данными, "упакованными" в строку, предоставляют функции pack и unpack. Их мы рассомотрим в одном из следующих выпусков.
А теперь, как я и обещал в прошлом выпуске, мы рассмотрим большую тему - регулярные выражения и их использование.
Регулярные выражения
Когда говорят о том, что Perl имеет мощные встроенные средства для обработки текстов, то обычно имеют в виду в первую очередь такие средства, как регулярные выражения, а также операторы и функции, которые с ними работают - операторы поиска, замены и т.д.
С помощью операторов и функций, которые используют регулярные выражения, Вы можете "за одно действие" производить такие операции с текстом, для реализации которых с помощью "обычных", базовых функций работы с текстом (которые мы изучали до этого) потребуется не один десяток строк программного кода.
Регулярное выражение ("Regular Expression", вам могут также встретиться аббревиатуры "regexp" и "regex") представляет собой строку символов, задающую шаблон искомого текста. Шаблон задает, так сказать "общий вид", "схему" текстового фрагмента. Несколько забегая вперед, скажу, что шаблоны в общей сложности может состоять из "обычных" символов и метасимволов, которые "обозначают" символы определенного класса (скажем, существуют метасимволы "любой симовол", "цифровой символ" и т.д.). Соответствие текстового фрагмента шаблону означает, что этот фрагмент можно описать данным шаблоном.
Сама идея шаблонов для поиска далеко не новая. Простейшая система поиска по шаблону реализована во многих операционных системах для поиска или фильтрации файлов. Обычно она поддерживает два метасимвола: '?', обозначающий "любой символ", и '*', обозначающий "любое количество любых символов". Так, если Вам надо найти все файлы с расширением 'txt', Вы ищете по шаблону '*.txt'; если все файлы вообще, то по шаблону '*.*'. Т.е. Вы задаете как бы "общий вид" (схему, шаблон) имени файла.
Шаблоны в Perl - это гораздо более "продвинутая", сложная (но в то же время - и гораздо более "могучая") система. В ней гораздо больше метасимволов и других средств. Поэтому многие считают, что работа с шаблонами - это одна из самых сложных тем в Perl-програмиировании.
Однако другая правда заключается в том, что нет необходимости сразу учить все возможности и вникать во все нюансы, т.к. имея даже базовые знания и навыки в области использования шаблонов, Вы уже сможете легко решать многие свои практические задачи.
Синтаксис регулярных выражений
Регулярные выражения имеют много общего со строками в двойных кавычках: в них также подставляются значения переменных и escape-последовательности.
Как я говорил выше, регулярное выражение может содержать "обычные" символы и метасимволы.
В частном случае регулярное выражение может представлять собой простую строку символов. Такой шаблон может использоваться для поиска строго определенной последовательности символов.
Однако чаще необходимо произвести поиск или разбор фрагмента текста, который заранее не известен, а известен лишь его "общий вид", "схема".
Для этого в шаблонах используются следующие метасимволы:
\ - считать следующий метасимвол обычным символом
^ - начало строки
$ - конец строки
. - любой символ
\w - буквенный символ ("word character"; к этому классу относятся
лфавитные символы, цифровые символы и символ подчеркивания)
\W - не буквенный символ
\s - пробельный символ
\S - непробельный символ
\d - цифровой символ
\D - нецифровой символ
() - группа
(вариант1|вариант2|вариант3) - альтернативные соответствия
[] - класс символов
По умолчанию как обычный символ, так и метасимвол соответствуют в искомой строке одному символу. Для того, чтобы символ в шаблоне соответствовал не одному (или не строго одному) символу, после него необходимо поставить модификатор количества ("quantifier"), который будет показывать, сколько раз подряд (или в каких пределах) может встречаться такой символ.
Определены следующие модификаторы количества:
* - 0 или более раз
+ - 1 или более раз
? - 0 или 1 раз
{n} - строго n раз
{n,} - не менее n раз
{n,m} - не менее n раз и не более m раз
Таким образом, модификатор '*' эквивалентен {0,}, '+' эквивалентен {1,}, а '?' эквивалентен {0,1}.
Метасимволы "нулевой ширины" ("zero-width assertions")
Также в Perl определены метасимволы "нулевой ширины", которые соответствуют не символам, а различным позициям и границам:
\b - граница слова
\B - не граница слова
\A - начало строки
\Z - конец строки или позиция перед символом новой строки
\z - конец строки
\G - позиция указателя pos(). Более подробно см. в описании оператора
поиска
Работа некоторых метасимволов зависит от используемогов строке языка. Для корректной обработки национальных символов (в т.ч. русского) необходима директива use locale и корректные региональные настройки на компьютере.
Круглые скобки
Отдельные части регулярного выражения могут быть заключены в круглые скобки. В этом случае, при успешном поиске, зарезервированным переменным $1,$2,$3 и т.д. будут присвоены части найденного текстового фрагмента, которые соответствуют заключенным в скобки частям шаблона: переменной $1 - содержимое, соответствующее первым скобкам, $2 - вторым и т.д. Эти переменные доступны только для чтения.
Например:
$txt='user@host.com'; $txt=~/(.*)@(.*)\.(.*)/; print "$1,$3,$2"; # Результат: "user,com,host"
(в приведенном примере перед точкой, обозначающей точку :-), стоит символ '\', который указывает, что следующий символ следует считать обычным, а не метасимволом).
Если в скобках указать несколько разных фрагментов шаблона, разделенных вертикальной чертой '|', то будет проверяться на соответствие каждый из этих вариантов. Это удобно, скажем, когда нужно проверить, соответствует ли строка одному из заранее заданных вариантов.
Пример:
if ($text=~/^(yes|no)$/i){print "ответ корректный";}; Метасимволы ^ и $ позволяют "привязать" искомое выражение соответственно к началу и/или концу строки. Благодаря использованию этих символов в шаблоне вышеприведенного примера, этому шаблону будут соответствовать именно строчки "yes" и "no", а не любые строчки, содержащие в середине эти слова.
Основные операторы и функции, использующие регулярные выражения
1. Оператор поиска по шаблону
(его еще называют оператором сопоставления с шаблоном)
строка=~m/шаблон/опции
или, в сокращенном варианте,
строка=~/шаблон/опции
Оператор поиска позволяет искать в строке фрагменты, соответствующие шаблону. В большинстве случаев шаблон "обрамляется" символами прямого слэша; в этом случае может применяться сокращенная форма этого оператора (без буквы m). Однако, в принципе, для обрамления шаблона может использоваться любой неалфавитный, нецифровой и непробельный символ. Это может быть нужно, если, скажем, сам шаблон содержит символ прямого слэша. В этом случае обязательно указывать букву m.
$a=~m/text/; # Ищем слово text: основной вариант,
$a=~m-text-; # но допустимо и так,
$a=~m~text~; # и даже вот так.
Примечание: если для обрамления шаблона использован символ одинарной кавычки, то значения переменных в него подставляться не будут (как и в любые строки, заключенные в одинарные кавычки). Если для этих целей использован вопросительный знак, значения переменных будут подставлены только один раз (аналогично опции 'o' в операторах поиска и замены).
if ($text=~/word/) {print "переменная text содержит слово word";};
Лирическое отступление: заметьте, что сокращенная форма оператора поиска (в данном случае он, скорее, оператор сопоставления с шаблоном) напоминает математическое "приблизительно равно". На мой взгляд, это символично - в том смысле, что этот оператор действительно похож на оператор сравнения, но в данном случае речь идет не о строгом сравнении, а как бы о приблизительном :-), т.е. просто о сопоставлении с шаблоном.
Для управления параметрами поиска программист может указывать следующие опции:
g - глобальный поиск: искать все соответствия, а не только первое;
i - игнорировать регистр символов;
s - представлять исходный текст как одну строку;
m - представлять исходный текст как многострочный;
o - компилировать шаблон только один раз;
c - не сбрасывать указатель в конце строки (при последнем поиске);
x - использовать расширенные регулярные выражения.
Если нужно указать несколько опций, просто перечислите их одну за другой (без пробелов и разделителей):
$string=~/Word/gi;
При использовании опции s все содержимое переменной рассматривается как одна строка, даже если ее содержимое представляет собой несколько строк с разделителями. При этом метасимволы '$' и '^' соответствуют началу и концу переменной, а разделители строк в переменной воспринимаются как обычные символы. При использовании опции m метасимволы '$' и '^' соответствуют началу и концу каждой строки, а символ разделителя строк воспринимается именно как символ, разделяющий строки, и в каждой строке поиск ведется отдельно.
Поскольку в регулярное выражение подставляются значения переменных, шаблон "компилируется" в конкретное значение каждый раз перед его использованием. Если указана опция o, то шаблон компилируется только один раз.
Возвращаемый оператором поиска результат во многом определяется тем, указана ли опция g (глобальный поиск) и имеются ли в регулярном выражении элементы в круглых скобках.
Для начала рассмотрим поведение оператора в режиме глобального поиска.
В списковом контексте оператор поиска возвращает список найденных соответствий. Если регулярное выражение содержит элементы в скобках, то возвращается список соответствий этим скобкам.
Так, если шаблон содержит три элемента в скобках и найдено два соответствия шаблону, то будет возвращен список из 6 элементов.
Если шаблон не содержит скобок, то с опцией g возвращается просто список всех найденных соответствий шаблону. Это эквивалентно тому, как если бы весь шаблон был бы заключен в скобки.
Если ни одного соответствия не найдено, то в любом случае возвращается пустой список.
В скалярном контексте оператор поиска организует последовательный поиск. Для строки, в которой производится поиск, Perl организует указатель текущей позиции. Изначально указатель указывает на начало строки. При вызове оператора поиска в скалярном контексте он ищет соответствие шаблону, начиная с позиции указателя. Если соответствие найдено, оператор возвращает "истина" (1) и устанавливает указатель на символ, следующий за найденным соответствием. Когда при очередном вызове оператора он не находит больше соответствий в оставшейся части строки, он возвращает "ложь" (пустая строка) и сбрасывает указатель на начало строки. Если не нужно, чтобы указатель сбрасывался после неудачного поиска, то необходимо использовать оператор поиска с опцией 'c'.
Значение указателя поиска можно просмотреть или изменить с помощью функции pos (переменная). Также отмечу, что значение указателя автоматически сбрасывается при изменении самой строки.
В следующем примере показан процесс последовательного поиска - в строке, содержащей 3 соответствия шаблону, 6 раз производится последовательный поиск и после каждого "шага" отображаются результат и позиция указателя:
$string="text1 text2 text3"; for ($i=1; $i<7; $i++){ $r=$string=~/text/g; if ($r==1){$result="found"} else {$result="not found";}; print "result=$result, pos=",pos ($string),"\n"; };
С помощью специального метасимвола \G можно "привязать" начало шаблона к текущей позиции указателя поиска, и таким образом организовать поиск "по цепочке" - когда следующее соответствие должно начинаться строго там, где закончилось предыдущее.
Без опции g оператор поиска ищет один раз, до первого соответствия. Это удобно, когда нужно произвести не поиск фрагментов в строке, а сопоставление строки с шаблоном (соответствует строка шаблону или нет) и выделение элементов строки по шаблону (с использованием скобок).
В скалярном контексте оператор возвращает "истина", если соответствие в строке найдено, или "ложь", если нет. В списковом контексте, если соответствие найдено, то возвращается список элементов, соответствующий содержимому круглых скобок в шаблоне. Если в шаблоне круглых скобок нет, то возвращается список из одного- единственного элемента "1" (в отличие от использования опции g, когда в этом случае возвращается список соответствий). Если соответсвие не найдено, то возвращается пустой список.
2. Оператор замены
строка=~s/шаблон/замена/опции
Оператор замены, подобно оператору поиска, ищет в строке фрагменты, соответствующие указанному шаблону, и заменяет их на другие.
Разделительные слэши могут быть заменены любыми неалфавитными, нецифровыми и непробельными символами.
В качестве результата он возвращает количество произведенных замен. Если ни одной замены не было сделано (не найдено ни одного соответствия шаблону), то возвращается "ложь" (пустая строка).
$string="text1, text2, text3"; $q=$string=~s/text/word/g; print "q=$q, string=$string"; #Результат: q=3, string=word1, word2, word3
Опции в операторе замены практически те же, что и в операторе поиска.
Опция e дает Perl понять, что строку "замена" следует рассматривать не как заменяющую строку, а как выражение, РЕЗУЛЬТАТ КОТОРОГО нужно использовать в качестве замены. Это придает оператору замены значительную гибкость, особенно учитывая то, что переменные $1,$2 и т.д. тоже могут участвовать в этом выражении. Таким образом, например, заменяющая строка может быть функцией от строки заменяемой.
Следующий пример ищет в строке значения года (2xxx, где x - цифра) и увеличивает все такие значения на 1:
$text="01.01.2005"; $text=~s/(2\d\d\d)/$1+1/ge; print $text;Каждый раз, когда оператор замены найдет заданную последовательность символов, будет произведено вычисление выражения $1+1 (поскольку у нас весь шаблон заключен в скобки, то в переменную $1 запишется полностью найденное соответствие) и подстановка полученного результата на место найденного соответствия.
Подобным же образом можно легко, "в одну строку" организовать перекодировку символов строки по принципу "замена байта на байт" (скажем, преобразование русского текста из одной кодировки в другую). Предположим, у нас определен массив @table из 256 элементов (0-255), содержащий таблицу перекодировки. Тогда:
$text=~s/(.)/chr($table[ord($1)])/ge;
Функции split и join
parts=split /шаблон/,$text;
Ранее мы уже рассматривали кратко эту функцию. Если Вы помните, она разбивает строку $text на части и возвращает их в виде списка. В качестве разделителей она использует части текста строки, соответствующие регулярному выражению /шаблон/.
Функция join (разделитель, массив) делает обратную операцию - "соединяет" элементы массива в одну строку, используя при этом указанный разделитель. Понятно, что в качестве разделителя в функции join указывается не регулярное выражение, а обычная строка.
На сегодня все. Я надеюсь, что не сильно "загрузил" этот выпуск рассылки. В следующем выпуске мы закончим тему регулярных выражений и сделаем еще кое-что интересное.
Обратите внимание на другие наши рассылки:
Сайт "AC-Power: все про Интернет и для него" предназначен как для пользователей Интернет, так и для веб-мастеров. На сайте есть статьи для пользователей сети Интернет, FAQ по работе в Интернет, интересные он-лайн сервисы и раздел, посвященный хостингу. Планируется введение новых интересных разделов. Если Вы хотите быть в курсе обновлений этого сайта, подпишитесь на эту рассылку. | |
| Наш сайт "CGI-Scripts.Info: все о CGI-скриптах" полностью посвящен языку Perl и созданию CGI-скриптов на этом языке. Есть коллекция бесплатных CGI-скриптов и коллекция программ на Perl. Подписавшись на эту рассылку, Вы будете получать оперативную информацию об обновлениях сайта: новых разделах, статьях, новых скриптах и новых версиях "старых" скриптов. |
Успехов!
Андрей
angel07@inbox.ru
Subscribe.Ru
Поддержка подписчиков Другие рассылки этой тематики Другие рассылки этого автора |
Подписан адрес:
Код этой рассылки: inet.webbuild.perlcgi |
Отписаться
Вспомнить пароль |
В избранное | ||