В Перл существует три типа структур данных: скаляры, массивы скаляров и хеши (hashes) – ассоциативные массивы скаляров. Обычно элементы массивов индексируются целыми числами, первый элемент – нулевой. Отрицательное значение индекса обозначает номер позиции элемента с конца. Хеши индексируются строками символов.
Имена скалярных переменных всегда начинаются с символа '$' даже когда обозначают элемент массива.
Пример:
$var1 # Простой скаляр 'var1'
$var1[0] # Первый элемент массива 'var1'
$var1{'first'} # Элемент с индексом 'first'
В случае использования имени массива «целиком» или его «среза» перед именем массива ставится символ '@'.
Пример:
@var1 # Все элементы массива var1 ( $var1[0], $var1[1], ... $var1[n])
@var1[1,3,10] # Элементы $var1[1], $var1[3], $var1[10]
@var1{'first','last'} # то же что и ( $var1{'first'}, $var1{'last'} )
Хеш «целиком» начинается с символа '%'.
Пример:
%var, %key, %years
Имена подпрограмм начинаются символом '&' если из контекста не видно
что это подпрограмма.
Пример:
&sub1, &test_prog, test(12)
Имена таблиц символов всегда начинаются символом '*'.
Каждый тип переменных имеет свою область памяти поэтому $var1 и $var1[0] совершенно разные переменные, хотя $var1[0] часть массива @var1. Так же @var1 и %var1 – разные массивы переменных.
Имена переменных могут содержать любые буквенно-цифровы символы за исключением пробела и табуляции. Эти смволы используются в качестве разделителей.
Большие и малые буквы различаются поэтому $var1 и $Var1 – разные переменные. В Перл по умолчанию имена меток и указателей файлов пишут большими буквами.
Контекст.
Большое значение для правильного употребления встроенных функций имеет контекст использования результата этих функций т.к. в противном случае они возвращают совершенно «непонятный» результат.
В Перл имеется два главных контекста: скалярный и список (list).
Проще говоря если в левой части выражения имеется ввиду одно единственное значение – то это скалярный контекст. Если множество значений – список.
Пример:
$var1 = <>; # Прочитать одну строку файла
@var1 = <>; # Прочитать все строки файла в массив @var1
$var1 = (1,2,3); # $var = 3 – количество элементов
@var1 = (1,2,3); # Создание массива @var1 с элементами 1,2,3
Скалярные значения.
Все данные в Перл это скаляры, массивы скаляров и хеши скаляров.
Скалярные переменные могут содержать числа, строки и ссылки.
Преобразование числа – строки происходит автоматически по умолчанию.
Скаляр может иметь только одно единственное значение, хотя это может быть ссылка на массив скаляров. Так – как Перл сам преобразовывает числа в строки и наоборот то программисту нет необходимости думать о том что возвращает функция.
В Перл не существует типов «строка» или «число» или «файл» или что то еще.
Это контекстно зависимый полиморфный язык для работы с текстами.
Скаляр имеет логическое значение "TRUE" (истина) если это не нулевая строка или число не равное 0.
В Перл существует два типа нулевых (null) скаляров – определенные (defined) и не определенные (undefined). Не определенное значение возвращается когда что-то не существует. Например не известная переменная, конец файла или ошибка. С помощью функции defined() вы можете заранее обнаружить подобное состояние.
Количество элементов массива так же является скаляром и начинается символами $# подобно интерпретатору csh. Фактически $#var1 – это индекс последнего элемента массива. Нужно помнить что первый элемент имеет индкес 0 поэтому количество элементов определяется как $#var1+1 . Присвоение значения $#var1 – изменит длину массива и разрушит «оставленные» значения.
Присвоение значения элементу массива с индексом больше чем $#var1
– увеличит размер массива, а присвоение ему нулевого списка – обнулит.
В скалярном контексте имя массива возвращает его длину (для списка возвращается последний элемент).
Пример:
@var1 = (4, 3, 2, 1); # Присвоение значения элементам массива
$i = @var1; # Использование скалярного контекста
print $i; # Печать результата 4 – кол-во элементов
print @var1; # Списковый контекст, печать всех элементов.
Для принудительного получения скалярного значения удобно применять функцию scalar().
Пример:
print scalar(@var1); # Вывод длины массива а не его значений
Хеш в скалярном контексте возвращает «true» если существует хотя бы одна пара «ключ-значение». Фактически возвращается строка типа 2/8 где 8 – количество выделенных «ячеек» памяти, а 2 – количество использованных.
Конструкторы скаляров.
Числа пишутся стандартно:
123
123.123
0.12
.12E-10
0xABCD # Шестнадцетиричная запись
0377 # Если 0 в начале – восьмеричная
123_456_123 # Так тоже можно для удобства чтения.
Строки ограничиваются одинарными (') или двойными (") кавычками:
'Ровняйсь, смирно!'
«Построемся и спасемся.»
Способов обозначения строк очень много. Плодробно смотрите описание оператора qq.
В хеше можно опускать кавычки если индекс не содержит пробелов.
Пример:
$var1{first} то же что и $var1{'first'}
Обратите внимание на то что перед первой одинарной кавычкой должен стоять пробел иначе строка воспримется как имя переменной так-как в именах разрешено использование одинарных кавычек.
Запрещается в кавычках применять зарезервированные литералы __LINE__ (номер текущей строки программы), __FILE__ (текущий файл).
Для обозначения конца программы можно применять литерал __END__
Весь последующий текст игнорируется, но его можно прочитать использую указатель файла DATA.
Слова в программе не поддающиеся ни какой интепретации воспринимаются как строки в кавычках поэтому рекомендуется имена меток и указателей файлов писать большими буквами для избежания возможного «конфликта» с зарезервированными словами.
В Перл есть возможность вставлять текст документа прямо в программу.
Так называемый "here-doc" (здесь текст) метод. Обозначается символами << за которым идет слово-ограничитель.>
Пример:
print <
Эй вы трое, идите двое сюда!
Полковник Савонькин.
EOF
Конструкторы списков.
Список – множество значений перечисленных через запятую и заключенных в круглые скобки. В списковом контексте список возвращает последний элемент списка.
Пример:
@var1 = (1, 2, 'привет', 1.2); # Присвоить значение элементам.
где
$var1[0] = 1,
$var1[1] = 2,
$var1[2] = 'привет'
$var1[3] = 1.2
$var1 = (1, 2, 'привет', 1.2);
а здесь $var1 = 1.2 т.е. последнее значение списка.
Допускается применять в списке другие списки, но в полученном списке уже невозможно различить начало и конец включенных списков.
Пример:
@s1 = (1, 2, 3); # Первый список
@s2 = (6, 7, 8); # Второй
@s = (0, @s1, 4, 5, @s2, 9, 10); # Включаем списки @s1 и @s2
print @s; # Результат: 012345678910 – значения без пробелов.
Список без элементов обозначаестя как () и называется нуль-списком.
Списковое выражение можно употреблять как имя массива, но при этом его нужно брать в круглые скобки.
Пример:
print ('январь','февраль','март')[1];
Результат: февраль
Список может быть присвоен списку только если каждый элемент в списке в левой части выражения допустим по типу списку в правой части.
Пример:
($a, $b, $c) = (1, 2, 3); # $a = 1, $b = 2, $c = 3
Присваивание списков в скалярном контексте возвращает количество присвоенных элементов.
Пример:
$x = (($a, $b, $c) = (1,2)); # Результат $x=2
В случае присваивания списка хешу список разсматривается как пары: ключ-значение.
Пример:
%дни_месяца = ('январь', 31, 'февраль', 30);
Результат: $дни_месяца{январь} = 31, $дни_месяца{февраль} = 30
Для удобства записи можно использовать выражение с => .
Пример:
%дни_месяца = (
январь => 31,
февраль => 30,
);
Тип typeglobs
В Перл используется специальный внутренний тип typeglog для записи массива всех переменных. Такие массивы начинаются с символа '*'. Их удобно применять для передачи ссылок на массивы и хеши, но в данной версии Перл уже есть возможность применять ссылки поэтому это делается очень редко. Единственно где это необходимо так это для работы со ссылками на файлы. Например если вам нужно создать локальную ссылку на файл в процедуре то это лучше сделать так:
sub new_sub
{ local *IN; # Ссылка на файл
open (IN, «test») || return undef; # Открыть файл. Возврат при ошибке.
.........
return;
}
Более подробно это описано в главе Ссылки.
Встроенные переменные Перл
Описанные в данной главе переменные имеют в Перл специальные значения.
Они обозначаются несколько непривычно для «глаза» программистов т.к. состоят обычно только из дву символов причем первый это '$' символо с которого начинаются имена всех переменных и произвольный часто не буквенно-цифровой символ. Если вы хотите пользоваться их «нормальными» буквенными синонимами то вам нужно указать в начале программы:
use English;
Точно так же если вы захотите пользоваться переменными и методами текущего указателя файлов вы можете написать:
use FileHandle;
после этого можно можно просто писать:
метод указатель выражение
или
указатель -> метод(выражение)
Ниже приводятся имена как в короткой так и в длинной (словесной) форме.
Некоторые из встроенных переменных имеют доступ тоько на чтение поэтому изменить их значение просто не возможно.
$_
$ARG
Переменная – по умолчанию для операторов ввода и поиска. То есть если в качестве аргумента не указана никакая переменная то используется именно эта.
$цифра
Содержит найденные подстроку в последнем поиске когда шаблон содержит метасимволы в круглых скобках. Цифра в данном случае это номер скобок. Первая подстрока имеет номер 1.
$&
$MATCH
Найденная подстрока в последнем поиске по шаблону.
$`
Подстрока предшевствующая найденной подстроке.
$'
$POSTMATCH
Подстрока последующая за найденной подстрокой.
$+
$LAST_PAREN_MATCH
Подстрока найденная в поиске с выбором по «или».
$*
$MULTILINE_MATCHING
Если значение этой переменной установить равным 1 то переменная в которой осуществляется поиск будет считаться многосторочной т.е. содержащей символы '\n' – перевод строки. Если значеие равно 0 то переменная считается однострочной. В Перл версии 5 и выше не рекомендуестя использовать эту переменную.
$.
$INPUT_LINE_NUMBER
$NR
Номер прочитанной строки последнего оператора ввода. Закрытие файла вызывает очистку значения этой переменной.
$/
$RS
$INPUT_RECORD_SEPARATOR
Символ – признак конца входной строки. По умолчанию это '\n'
$|
$OUTPUT_AUTOFLUSH
Если присвоить этой переменной не нулевое значение то будет сброс буфера вывода после каждой операции вывода. Значение по умолчанию -0
$,
$OFS
$OUTPUT_FIELD_SEPARATOR
Символ добавляемый оператором print после каждого элемента из списка параметров.
$\
$ORS
$OUTPUT_RECORD_SEPARATOR
Символ добавляемый print после вывода всех параметров.
$"
$LIST_SEPARATOR
Анологичен «$,» но добавляется после каждого элемента массива указаноого в «....».
$;
$SUBSEP
$SUBSCRIPT_SEPARATOR
Символ – разделитель для эмуляции многомерных массивов в хеш массивах. По умолчанию '\034'.
$#
$OFMT
Формат по умолчанию для вывода чисел.
$%
$FORMAT_PAGE_NUMBER
Формат по умолчанию для вывода номеров страниц.
$=
$FORMAT_LINES_PER_PAGE
Длина одной страницы. По умолчанию 60 строк.
$-
$FORMAT_LINES_LEFT
Количество оставшихся строк на странице.
$~
$FORMAT_NAME
Имя формата текущего вывода. По умолчанию имя указателя.
$^
$FORMAT_TOP_NAME
Имя текущего формата для заголовка страницы.
$:
$FORMAT_LINE_BREAK_CHARACTERS
Символы переноса строки для многострочных полей. В строке формата такие поля начинаются символом '^'. По умолчанию '\n-'.
$^L
$FORMAT_FORMFEED
Символ перевода формата ( смены листа). По умолчанию '\f'.
$^A
$ACCUMULATOR
Текущее значение аккумулятора функции write() для format(). Значение этой переменной можно увидеть только при использовании функции formline() т.к. write() очищает ее после каждого вывода.
$?
$CHILD_ERROR
Данная перменная содержит статус завершения таких процессов как: закрытие pipe, завершение функций system(), wait() и `...`.
$!
$ERRNO
$OS_ERROR
В числовом контексте возвращает код ошибки errno.
В строковом – строку сообщения об ошибке. Можно принудительно присвоить этой перменной код ошибки что бы получить системное сообщение для данного кода или установить код завершения для функции die().
$@
$EVAL_ERROR
Сообщение об ошибке последней команды eval().
$$
$PID
$PROCESS_ID
Номер текущего процесса.
$<
$UID
$REAL_USER_ID
Реальный UID текущего процесса.
$>
$EUID
$EFFECTIVE_USER_ID
Эффективный UID текущего процесса.
$(
$GID
$REAL_GROUP_ID
Реальный GID текущего процесса.
$)
$EGID
$EFFECTIVE_GROUP_ID
Эффективный GID текущего процесса.
$O
$PROGRAM_NAME
Имя файла программы. Если этой переменной присвоить какое нибудь значение то его можно видеть в команде ps, что удобно для контроля за состоянием программы.
$[
Номер первого элемента массива или символа строки. Значение по умолчанию – 0.
$]
$PERL_VERSION
Строка сообщение версии Перл. Печатается по команде perl -v Применяется в программе для определения рабочей версии Перл. В числовом контексте это номер версии плюс номер модификации / 1000.
$^D
$DEBUGGING
Текущее значение ключа отладки '-D'.
$^F
$SYSTEM_FD_MAX
Номер максимального системного описателя файлов (system file descriptor). Обычно это 2.
$^I
$INPLACE_EDIT
Текущее значение inplace-edit возможности. Для отключения используйте undef.
$^P
$PERLDB
Внутренний флаг отладки. Применяется для того что бы отладчик не отслеживал самого себя.
$^T
$BASETIME
Время в секундах с начала 1970 года старта текущей программы.
$^W
$WARNING
Значение флага '-w'. true -если включено и false – выключено.
$^X
$EXECUTABLE_NAME
Команда запуска Перл. Аналогично argv[0] в С.
$ARGV
Имя текущего файла читаемого оператором '<>'.
@ARGV
Массив параметров строки запуска программы. Внимание! @#ARGV – меньше количества параметров на 1 т.к. $ARGV[0] это первый параметр (не имя программы).
@INC
Список директорий диска которые просматривает Перл для выполнения команд do, require или use.
%INC
Этот хеш содержит имена директорий для имен использованных файлов командами do или require. Ключ – имя файла, а значение – директория.
$ENV{выражение}
Хеш %ENV содержит значения переменных окружения. Изменение этих значений вызывает изменение окружения для процессов потомков.
$SIG{выражение}
Хеш %SIG содержит имена подпрограмм для системных сигналов таких как INT, QUIT, PIPE, ... Значение 'DEFAULT' – для системной обработки. 'IGNORE' – игнорировать данный сигнал.
Регулярные выражения (шаблоны)
В данной главе описывается синтаксис регулярных выражений. Чаще всего в Перл они используюстя в операторах поиска и замены таких как s// m/ операторах связки =~ или != и т.д.
Как правило все эти операторы имеют схожие опции такие как:
i – не различать строчные и заглавные буквы.
m – считать строку многострочной.
s – однострочная строка.
x – расширенный синтаксис ( использование пробелов и комментариев)
Обычно все эти опции обозначают как '/x'. Их можно использовать даже внутри шаблонов, используя новую конструкцию (?...)
Регулярные выражения или шаблоны (pattern) то же самое что и regexp процедуры в Юниксе. Выражения и синтаксис заимствован из свободно распространяемых процедур V8 Генри Спенсера (Henry Spencer) там же они подробно и описаны.
В шаблонах используются следующие метасимволы (символы обозначающие группы других символов) часто называемых egrep – стандартом:
\ – считать следующий метасимвол как обычный символ.
^ – начало строки
. – один произвольный символ. Кроме '\n' – конец строки.
$ – конец строки
| – альтернатива (или)
() – группировка
[] – класс символов
Метасимволы имеют модификаторы (пишутся после метасимвола):
* – повторяется 0 или большее число раз
+ – повторяется 1 или большее число раз
? – 1 или 0 раз
{n} – точно n раз
{n,} – по меньшей мере раз
{n,m} – не менше n, но и не больше m
Во все других случаях фигурные скобки считаются обычными (регулярными) символами. Таким образом '*' эквивалентна {0,} , '+' – {1,} и '?' – {0,1}. n и m не могут быть больше 65536.
По умолчанию действие метасимволов «жадно» (greedy). Совпадение распространяется столько раз сколько возможно не учитывая результат действия следуюющих метасимволов. Если вы хотите «уменьшить их аппетит» то используйте символ '?'. Это не изменяет значение метасимволов просто уменьшает распространение. Таким образом:
*? – станет 0 и более
+? – 1 и более
?? – 0 или 1 раз
{n}? – точно n раз
{n,}? – не меньше n раз
{n,m}? – больше или равно n и меньше m раз
Шаблоны работают так же как и двойные кавычки поэтому в них можно использовать `\` – символы (бакслэш-символы):
\t – символ табуляции
\n – новая строка
\r – перевод каретки
\A – перевол формата
\v – вертикальная табуляция
\a – звонок
\e – escape
\033 – восьмеричная запись символа
\x1A – шестнадцатеричная
\c[ – control символ
\l – нижний регистр следующего символа
\u – верхний регистр -//-
\L – все символы в нижнем регистре до \E
\U – в верхнем -//-
\E – ограничитель смены регистра
\Q – отмена действия как метасимвола
Дополнительно в Перл добавлены следующие метасимволы:
\w – алфавитно-цифровой или '_' символ
\W – не алфавитно-цифровой или '_' символ
\s – один пробел
\S – один не пробел
\d – одна цифра
\D – одна не цифра
Обратите внимание что все это «один» символ. Для обозначения последовательности применяйте модификаторы. Так:
\w+ – слово
\d+ – целое число
[+-]?\d+ – целое со знаком
[+-]?\d+\.?\d* – число с точкой
Кроме того существуют мнимые метасимволы. Обозначающие не существующие символы в месте смены значения. Такие как:
\b – граница слова
\B – не граница слова
\A – начало строки
\Z – конец строки
\G – конец действия m//g
Граница слова (\b) – это мнимая точка между символами \w и \W.
Внутри класса символов '\b' обозначает символ backspace (стирания).
Метасимволы \A и \Z – аналогичны '^' и '$' но если началостроки '^' и конец строки '$' действуют для каждой строки в многосторочной строке то \A и \Z обозначают начало и конец всей многосторчной строки.
Если внутри шаблона применяется группировка (круглые скобки) то номер подстроки группы обозначается как '\цифра'.
Заметьте что за шаблоном в пределах выражения или блока эти группы обозначаются как '$цифра'. Кроме этого существуют дополнительные переменные:
$+ – обозначает последнее совпадение
$& – все совпадение
$` – все до совпадения
$' – все после совпадения
Пример:
$s = «Один 1 два 2 и три 3»;
if ($s =~ /(\d+)\D+(\d+)/)
{
print «$1\n»; # Результат '1'
print «$2\n»; # '2'
print «$+\n»; # '2'
print «$&\n»; # '1 два 2'
print «$`\n»; # 'Один '
print «$'\n»; # ' и три 3'
}
Перл версии 5 содержит дополнительные конструкции шаблонов:
(?#комментарий) – комментарий в теле шаблона.
(?:шаблон) – группировка как и '( )' но без обратной ссылки
(?=шаблон) – «заглядывание» вперед.
Например /\w+(?=\t)/ соответствует слову за которым идет табуляция но символ '\t' не включается в результат.
Пример:
$s = «1+2-3*4»;
if ($s =~ /(\d)(?=-)/) # Наити цифру за которой стоит '-'
{
print «$1\n»; # Результат '2'
}
else { print «ошибка поиска\n»;}
(?!шаблон) – «заглядывание» вперед по отрицанию.
Пример:
$s = «1+2-3*4»;
if ($s =~ /(\d)(?!\+)/) # Наити цифру за которой не стоит '+'
{
print «$1\n»; # Результат '2'
}
else { print «ошибка поиска\n»;}
(?ismx) – «внутренние» модификаторы. Удобно применять в шаблонах где например нужно внутри шаблона указать модификатор.
Правила регулярного выражения. (regex)
1. Любой символ обозначает себя самого если это не метасимвол. Если вам нужно отменить действие метасимвола то поставьте перед ним '\'.
2. Строка символов обозначает строку этих символов.
3. Множество возможных символов (класс) заключается в квадратные скобки '[]' это значит что в данном месте может стоять один из указанных в скобках символ. Если первый символ в скобках это '^' – значит не один из указанных символов не может стоять в данном месте выражения. Внутри класса можно употреблять символ '-' обозначающий диаппазон символов. Например a-z один из малых букв латинского алфавита, 0-9 – цифра и т.д.
4. Все символы, включая специальные можно обозначать с помощью '\' как в языке С.
5. Альтернативные последовательности разделяются символом '|' Заметьте что внутри квадратных скобок это обычный символ.
6. Внутри регулярного выражения можно указыват «подшаблоны» заключая их в круглые скобки и ссылаться на них как '\номер' Первая скобка обозначается как '\1'.
Операторы и приоритеты
В Перл ассоциативность и приоритетность операторов аналогична языку C Ниже перечислены все операторы в порядке уменьшения приоритета, в начале строки указана ассоциативность.
ассоц. операторы
– –
левая термы и левосторонные списковые операторы
левая ->
– ++ –
правая **
правая ! ~ \ унарные + и -
левая =~ !~
левая * / % x
левая + – .
левая << >>>
– именованные унарные операторы
– < > <= >= lt gt le ge
– == != <=> eq ne cmp
левая &
левая | ^
левая &&
левая ||
– ..
правая ?:
правая = += -= *= и т.д.
левая , =>
– правосторонние списковые операторы
левая not
левая and
левая or xor
Термы и левосторонние списковые операторы.
Любой терм имеет самый высокий приоритет. К терму относятся переменные, кавычки и их операторы, арифметические и логические выражения в скобках, любые функции с параметрами в скобках. Фактически таких функций нет так как это просто унарные и списковые операторы просто они ведут себя подобно функциям с параметрами в скобках. Подробно смотри главу «Функции».
Если после любого спикового оператора ( print(), и т.д.) или унарного оператора (chdir(), и т.д.) следует левая круглая скобка, то операторы внутри скобок имеют наивысший приоритет. Так же как и обычные функции.
Если скобки отсутсвуют то приоритет списковых операторов или наивысший или наименьший в отношении операторов справа или слева от него.
Например:
@i = ('a ','b ', print 'c ', 'd ');
print «\n»,@i,"\n";
Результат: