Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

CGI-программирование с самого начала - работа со строками #1


Информационный Канал Subscribe.Ru

Уважаемые подписчики!

Как я и обещал, сегодня мы рассмотрим работу со строками в языке Perl. Собственно говоря, это будет тема даже не одного, а нескольких выпусков.

Перед тем, как перейти непосредственно к работе со строками, мы совершим краткий экскурс по типам переменных языка Perl и основам работы с ними, а затем рассмотрим работу со встроенными функциями языка Perl.

Тем из Вас, для кого это первый выпуск рассылки, рекомендуем прочитать предыдущие выпуски, которые можно получить в архиве рассылки на Subscribe.ru. Он находится здесь.

Переменные в Perl

В Perl существуют всего три типа переменных - скаляры, массивы и ассоциативные массивы, которые еще называют хэшами (hash). Таким образом, типы переменных в Perl отличаются не видом хранимых значений, а способом их хранения.

Скаляр - это "основной" тип переменных, предназначенный для хранения чисел, строк и ссылок.

В языке Perl нет отдельных "числовых" и "строковых" переменных. Значение скалярной переменной "трактуется" как число или как строка в зависимости от выражения, в котором она используется.

Например,

$d="123";
print $d+1;                  #Результат 124
print $d."1";                #Результат 1231

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

Имена скалярных переменных начинаются с символа '$'. Также необходимо отметить, что имена переменных в Perl чувствительны к регистру символов (т.е. $DATA, $data и $Data - это три разные переменные).

Массивы представляют собой индексированный список скаляров. В Perl нумерация элементов массива начинается с 0. Имя массива начинается с символа '@'.

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

Например:


#Задаем массив
 @values=('value1','value2','value3');
#Получаем 2-й элемент массива в переменную $a.
$a=$values[1];
При использовании имени массива в скалярном контексте возвращается число его элементов:


$n=@values;
print $n;                   #Результат 3

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

Имя хэша начинается со значка '%'. При обращении к элементу по имени ключа последний указывается не в квадратных (как в случае с массивами), а в фигурных скобках. Как и с массивами, отдельный элемент обозначается значком '$'.


$PARAM{'name1'}='value1';
$PARAM{'name2'}='value2';
$PARAM{'name3'}='value3';

print $PARAM{'name2'};          #Результат: value2

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

Существуют функции, облегчающие работу с хэшами.

Функция keys ИМЯ_ХЭША возвращает список (массив) всех ключей данного хэша, а функция values ИМЯ_ХЭША - список всех значений. В скалярном контексте эти функции возвращают количество элементов в хэше. (понятно, что для одного и того же хэша количество ключей и их значений будет одинаковым) :-)

В следующем примере функция keys использована в цикле, перечисляющем элементы хэша:


foreach $key(keys %PARAM)
    {
    print "$key=$PARAM{$key}\n";
    };

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

(ключ1, значение1, ключ2, значение2 и т.д.)

 @P=%PARAM;
#Результат: @P=('name1','value1','name2','value2','name3','value3')
# (порядок ключей-значений может отличаться!)

Справедливо и обратное:

%PARAM2=@P;

В этом случае происходит обратная "упаковка" элементов массива в ключи и значения хэша.

Функции в Perl

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

Причем возвращаемое значение не обязательно должно быть скаляром (т.е. одним числом или одной строкой), оно может быть и массивом. Например, рассмотренная нами в одном из прошлых выпусков функция split возвращает в качестве результата массив строк. Более того, язык Perl "устроен" так, что одни и те же функции могут возвращать результат по-разному - в зависимости от того, что от функции ожидается - скаляр или массив. Ожидаемый "формат" результата определяется по контексту ее использования в выражении.

При этом говорят, что функция используется либо "в скалярном контексте", либо "в списковом контексте".

Так, например, функция localtime в скалярном контексте возвращает "читаемую" строку с текущими местными датой и временем, например,

Sat Jul 30 04:24:13 2005 ,

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

Если по контексту выражения не удается определить ожидаемый от функции формат результата, то Perl по умолчанию считает контекст функции списковым. Для "принудительного" указания функции в скалярном контексте можно использовать модификатор scalar. Он указывается непосредственно перед именем функции, например:

print scalar localtime;

Очевидно было бы предположить некоторые общие закономерности, какие-то правила преобразования "скалярного" результата в "списковый" и обратно (одинаковые для всех функций). Однако это НЕ ТАК. Единственное (и уж точно универсальное) правило на этот счет гласит, что здесь НЕТ НИКАКИХ ПРАВИЛ. :-) Результаты, возвращаемые функцией в различных контекстах, зависят от конкретной функции. Поэтому в описании каждой функции указывается, что она возвращает в скалярном контексте, а что - в списковом.

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

Другой "приятной мелочью" в языке Perl является то, что аргументы функций можно заключать в скобки, а можно и не заключать - это как Вам больше нравится :-)

Имена функций также чувствительны к регистру смиволов.

Работа со строками в Perl

Строка в Perl представляет собой последовательность символов. Причем символом могут в принципе являться не только "печатаемые" символы, но и любые байты - с кодом от 0 до 255.

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

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

Строки в Perl заключаются в одинарные либо в двойные кавычки.

Основное отличие между этими способами заключается в том, что строка в одинарных кавычках воспринимается Perl "как есть", а в строке, заключенной в двойные кавычки, производится подстановка значений переменных и escape-последовательностей (кодов спец. символов, начинающихся с '\',например, '\n', '\r').

Escape-последовательности позволяют легко и просто указать прямо в строке непечатаемые символы и символы, которые нельзя указать напрямую (например, сам символ двойной кавычки, который будет интерпретирован как конец строки).

Аналогичный механизм escape-последовательностей существует в C/C++ и других языках.

Например:


$a=1; $b=2; $c=3;
print "$a-$b--$c";                #Результат: 1-2--3

В одинарных кавычках единственные заменяемые последовательности - "\'" (заменяется на символ одинарной кавычки) и "\\" (заменяется на символ "\"). Поддержка этого "минимума" необходима для того, чтобы в самой строке можно было указать символ одинарной кавычки.

Функции работы со строками

Теперь перейдем к рассмотрению функций языка Perl, предназначенных для работы со строками.

Длину строки в символах можно узнать с помощью функции length СТРОКА.


$a="abcde";
print length $a;                   #Результат: 5

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

Формат функции substr следующий:


substr СТРОКА, СМЕЩЕНИЕ, ДЛИНА
где

СТРОКА - исходная строка, из которой необходимо выделить подстроку;

СМЕЩЕНИЕ - смещение искомой подстроки в исходной строке в символах. Если СМЕЩЕНИЕ=0, то подстрока берется от начала строки.

ДЛИНА - длина искомой подстроки в символах; если не указана, то подразумевается "до конца строки".

Пример:


$s="ABCDEFGH";
print substr ($s,2,3);               #Результат: CDE
print substr ($s,3);                 #Результат: DEFGH

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

Пример:


$s="ABCDEFGH";
substr ($s,2,3,'*');
print $s;                            #Результат: AB*FGH

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

Функция index ищет в строке заданную подстроку и возвращает смещение, по которому она нашла ПЕРВОЕ вхождение строки в подстроку:

index СТРОКА, ПОДСТРОКА, СМЕЩЕНИЕ

СТРОКА - строка, в которой надо искать

ПОДСТРОКА - подстрока, которую надо искать

СМЕЩЕНИЕ - необязательный параметр, задающий смещение, начиная с которого надо искать подстроку. Если не задан, поиск ведется с начала строки.

Функция rindex делает то же самое, только ищет не с начала, а с конца строки, и возвращает смещение не первого, а последнего вхождения подстроки.

Преобразование регистра символов - функции lc, uc, lcfirst и ucfirst

Иногда бывает нужно преобразовать строку текста к верхнему или нижнему регистру символов. Для этих целей в Perl предусмотрены функции lc и uc. Аргументом у них является строка, подлежащая преобразованию, а возвращают они преобразованную строку.

Например,


$d="aBcDeFg";
print lc $d;          # Результат: abcdefg
print uc $d;          # Результат: ABCDEFG

Функции lcfirst и ucfirst делают то же самое, только не для всей строки, а только для ее первого символа, а остальные остаются без изменений.

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

$d="IvAnOv";
$dn=ucfirst (lc $d);
print $dn;            #Результат: Ivanov

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

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

Особенности используемого языка вместе с другими региональными параметрами обычно задаются на уровне настройки операционной системы. В Windows за это "отвечает" элемент Панели управления "Язык и стандарты".

В Perl 5.004 и выше реализована возможность использования региональных настроек. Для этого надо где-нибудь в начале программы указать директиву

use locale;

По умолчанию (без этой директивы) их использование выключено для совместимости с более ранними версиями Perl.

Если Вы используете Perl под Windows, и у Вас в качестве языка в "Язык и стандарты" стоит "Русский", то эти функции (с директивой use locale) по умолчанию смогут корректно работать с русскими текстами в кодировке windows-1251.


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


Успехов!

Андрей
angel07@inbox.ru


Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: inet.webbuild.perlcgi
Отписаться
Вспомнить пароль

В избранное