Глава 10. Встроенные функции: обработка данных
Коротко
Perl содержит множество встроенных функций. Некоторые уже обсуждались в этой книге, например, функция push, добавляющая к массиву данные:
push (@array, "one");
push (@array, "two");
push (@array, "three");
print @$array[1];
one
В этой главе рассматриваются встроенные функции Perl, предназначенные для работы с данными и их обработки (сюда входят функции для работы со строками, сортировки данных, математические функции, функции для работы с массивами и хешами, и многое другое). Встроенные функции, используемые для операций ввода/вывода и взаимодействия между процессами будут рассмотрены в главе 11. Встроенным функциям, предназначенным для работы с файлами посвящена глава 12. Наконец, модули и функции, входящие во стандартную библиотеку модулей рассматриваются в главе 13.
Подсказка: Если вы внимательно посмотрите алфавитный список функций в документации, прилагающейся к Perl, то сможете обнаружить некоторые полезные функции, не описанные в этой главе.
Функции, рассматриваемые в этой главе (за исключением функций POSIX — Portable Operating System Interface) являются встроенными в Perl, так что с ними можно работать без дополнительных библиотек и файлов. Поскольку по ходу изложения большинствo приведенных здесь функций уже неоднократно использовалось, дополнительного введения не требуется. Итак, мы немедленно переходим к деталям.
Непосредственные решения
abs — абсолютное значение
Функция abs возвращает абсолютное значение аргумента. Если не указан аргумент значение, используется переменная $_:
abs значение
abs
Пример:
print abs -5;
5
atan2 — арктангенс
Функция atan2 возвращает арктангенс частного Y/X. Возвращаемое значение лежит в диапазоне от - SYMBOL 112 \f "SymbolProp BT" \s 10 до +SYMBOL 112 \f "SymbolProp BT" \s 10:
atan2 Y, X
В Perl нет встроенной функции, вычисляющей тангенс (хотя такая функция включеная в пакете POSIX — это POSIX::tan, см. далее раздел «функции POSIX»).
Подсказка: Вы всегда можете разделить синус на косинус чтобы получить тангенс.
chomp — удаление конца строки
Функция chomp удаляет символы новой строки (обычно \n), расположенные в конце текстовой строки. Она работает со строками или списками. Если не указан аргумент, используется переменная $_:
chomp переменная
chomp список-переменных
chomp
В качестве аргументов функции должны использоваться «левые значения» — то есть синтаксические конструкции, допустимые слева от оператора присваивания. Функция возвращает число удаленных символов. Если указан список переменных, то конец строки удаляется у каждой из них, но возвращаемое функцией значение соответствует только последней. Обычно chomp используется для удаления символа конца строки у введенного текста:
while (<>) {
chomp;
print;
}
В качестве символа конца строки используется содержимое специальной переменной $/.
chop — удаление последнего символа строки
Функция chop удаляет последний символ строки или списка строк. В качестве значения возвращается удаленный символ. Если не указан аргумент, используется переменная $_:
chop переменная
chop список-переменных
chop
В качестве аргументов функции должны использоваться «левые значения» — то есть синтаксические конструкции, допустимые слева от оператора присваивания. Если указан список переменных, то последний символ удаляется у каждой переменной, но возвращаемое функцией значение соответствует только последней. Пример:
while (<>) {
chop;
print;
}
Как правило, в подобных ситуациях рекомендуется использовать функцию chomp, а не chop, так как она «безопаснее»: удаляется именно символ конца строки, а не любой последний символ.
chr — преобразование числа в символ
Функция chr возвращает символ, код ASCII которого задан в качестве аргумента функции. Если не указан аргумент, используется переменная $_:
chr число
chr
Пример:
print chr 65;
A
cos — косинус
Функция cos вычисляет косинус аргумента, заданного в радианах. Если не указан аргумент, используется переменная $_:
cos выражение
cos
Чтобы вычислить арккосинус, можно воспользоваться функцией POSIX::acos из пакета POSIX (см. далее раздел «функции POSIX»).
each — пара ключ/значение из хешы
Функция each последовательно перебирает записи в хеше. В контексте списка функция возвращает пару (ключ, значение) для очередной записи. В скалярном контексте она возвращает очередное значение ключа:
each хеш
Вот пример применения функции each:
$hash{sandwich} = grilled;
$hash{drink} = ’rot beer’;
while (($key, $value) = each(%hash)) {
print "$key => $value\n";
}
drink => root beer
sandwich => grilled
При первом обращении к хешу each запоминает текущий элемент (точнее, делает пометку во внутреннем представлении хеша) и при последующих обращениях переходит к следующему элементу, пока не дойдет до конца хеша. По достижении последней записи, возвращается неопределенное значение (интерпретируемое как ложь), что может быть использовано в условных операторах и операторах цикла: чередуйте вызовы функции each применительно к одному или нескольким хешам в одном или нескольких местах сценария — поскольку пометка текущей записи связана с хешом, а не с внутренним состоянием функции или с точкой кода, в которой она вызывается, вызовы each будут работать правильно.
eval — компилирование и выполнение команд Perl
Функция eval используется для компиляции и выполнения команд Perl в процессе работы сценария:
eval выражение
eval {блок}
eval
Если в качестве аргумента задано выражение (которое должно иметь тип текстовой строки), то после его вычисления производится синтаксический анализ, компиляция и выполнение команд Perl, содержащихся в заданной строке. В отличие от строки, блок, то компилируется только один раз — а именно, в момент компиляции кода самого сценария. Если не указан аргумент, используется переменная $_.
Пример:
eval {print "Hello "; print "there.\n";};
Hello there.
Сообщение об ошибке, если она возникает, записывается в переменную $@.
exists — проверка ключа в хеше
Функция exists проверяет, существует ли в данном хеше указанный ключ:
exists выражение
Выражением должно быть «левое значение», соответствующее обращению к элементу хеша. Пример:
$hash{fruit} = apple;
$hash{sandwich} = hamburger;
$hash{drink} = bubbly;
if (exists($hash{"vegetable"})) {
print "Element exists.";
} else {
print "Element does not exists.";
}
Element does not exists
exp — вычисление экспоненциальной функции
Функция exp вычисляет результат возведения основания натуральных логарифмов (то есть числа e=2.71828182...) в заданную степень. Если не указан аргумент, используется переменная $_:
exp выражение
exp
Пример:
print exp 1;
2.71828182845905
hex — преобразование шестнадцатиричного числа
Функция hex преобразует текстовую строку, представляющую собой шестнадцатиричное число, к целому числу. Если не указан аргумент, используется переменная $_:
hex выражение
hex
Пример:
print hex "10";
16
index — положение подстроки
Функция index возвращает первую найденную позицию, на которой в строке расположена указанная подстрока:
index строка, подстрока, позиция
index строка, подстрока
Поиск подстроки начинается с заданной позиции. Если соотвествующий аргумент опущен, поиск ведется с начала строки. Если подстрока не найдена, функция index возвращает значение -1 (или значение, на единицу меньше базового индекса массивов, хранимого в переменной $[, если оно не ноль). Пример:
$text = "Here is the text!";
print index $text, "text";
12
int — целая часть числа
Функция int вычисляет целую часть выражения, заданного в качестве аргумента. Если не указан аргумент, используется переменная $_:
int выражение
int
Усечение до целой части ведется в направлении нуля. Функция не округляет, а усекает значение до целого — поэтому для округления величин вместо int нужно использовать встроенные функции sprintf и printf или функции POSIX::floor и POSIX::ceil из пакета POSIX. Пример:
print int 1.99999;
1
join — преобразование списка в строку
Функция join преобразует список в текстовую строку, вставляя между элементами списка заданный в первом аргументе разделитель:
join выражение, список
Функция возвращает в качестве результата строку. Выражение должно быть текстовой строкой или преобразовываться в нее. На сам список работа функции не влияет.
Пример:
@array = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
print join ("/", @array);
1/2/3/4/5/6/7/8/9/10
keys — список ключей хешы
В списковом контексте функция keys возвращает список, состоящий из всех ключей хеш. В скалярном контексте функция возвращает число — количество ключей:
keys хеш
Пример:
$hash{sandwich} = salami;
$hash{drink} = ’rot beer’;
foreach $key (keys %hash) {
print $hash{$key} . "\n";
}
root beer
salami
lc — преобразование букв к нижнему регистру
Функция lc возвращает строку, переданную в качестве параметра, преобразованной к нижнему регистру, то есть заменяет в выходной строке заглавные буквы на строчные. Если аргумент опущен, используется переменная $_:
lc выражение
lc
Пример:
print lc ’HELLO!’;
hello!
lcfirst — преобразование первой буквы к нижнему регистру
Функция lcfirst возвращает исходную строку, в которой первая буква (если это буква) преобразована к нижнему регистру (то есть заглавная буква заменяется на строчную). Если у функции не указан аргумент, используется переменная $_:
lcfirst выражение
lcfirst
Пример:
print lcfirst ’HELLO!’;
hELLO!
length — длина строки
Функция length возвращает длину (в байтах) своего аргумента. В качестве аргумента должно стоять выражение, преобразуемое в конечном счете к скаляру — текстовой строке. Если не указан аргумент, функция возвращает длину строки, содержащейся в переменной $_:
length выражение
length
Пример:
$text = "Here is the text.";
print lengthy $text;
17
log — натуральный логарифм
Функция log вычисляет натуральный логарифм аргумента, который должен быть числом. Если не указан аргумент, используется переменная $_:
log выражение
log
map — выполнить команду для каждого элемента списка
Функция map вычисляет выражение или выполняет блок команд для каждого элемента списка. В качестве результата она возвращает список полученных значений, в списковом, и число элементов списка, — в скалярном контексте:
map {блок}, список
map выражение, список
В следующем примере мы используем функцию uc для преобразования элементов массива к верхнему регистру:
@array = (a, b, c, d, e, f);
@array = map(uc, @array);
print join(", ", @array);
A, B, C, D, E, f
В момент выполнения блока команд или вычисления выражения очередной элемент списка заносится в специальную переменную Perl $_. (В частности, поэтому так хорошо работают совместно с map функции, использующие $_ как аргумент по умолчанию.) Вычисления проводятся в списковом контексте — в результате одно значение из входного списка может добавлять к выходному списку ни одного, один, или несколько элементов.[A1] Так, команда
%hash = map {getkey($_) => $_} @array;
— это просто сокращенный (и более быстрый) вариант цикла:
%hash = ();
foreach $_ (@array) {
%hash{getkey($_)} = $_;
}
Подсказка: Поскольку переменная $_ выступает в роли синонима элемента списка, можно изменять входной список с помощью блока команд. Однако, если в роли списка выступает не переменная-массив, результаты могут оказаться непредсказуемыми.
oct — преобразование восьмеричного числа
Функция oct выполняет преобразование текстовой строки, представляющей из себя восьмеричное число, к целому числу. Если не указан аргумент, используется переменная $_:
oct выражение
oct
Пример:
print oct "10";
8
ord — преобразование символа в код
Функция ord преобразует первый (только первый!) символ строки, заданной в качестве ее аргумента, в число (то есть в код символа согласно таблице ASCII). Если не указан аргумент, используется переменная $_:
ord выражение
ord
Пример:
print ord ’A’;
65
pack — упаковка значений
Функция pack получает на входе список значений и упаковывает их в бинарную структуру (скаляр), которую и возвращает в качестве результата:
pack шаблон, список
Для распаковки используется функция unpack с той же строкой-шаблоном, что указывалась при упаковке.
Здесь в качестве шаблона используется не регулярное выражение, а строка (последовательность букв), которая задает порядок и тип значений:
· @ — заполнение двоичными нулями до следующей абсолютной позиции
· a — текстовая строка, дополняемая двоичными нулями
· A — текстовая строка, дополняемая пробелами
· b —строка битов, упорядоченная по возрастанию старшинства битов (аналогична результату работы функции vec)
· B —строка битов, упорядоченная по убыванию старшинства битов
· c — однобайтовое целое (символ) со знаком
· C — однобайтовое целое (символ) без знака
· d — число с плавающей точкой двойной точности в естественном формате
· f — число с плавающей точкой ординарной точности в естественном формате
· h — шестнадцатиричная строка, в которой сперва идут младшие шестнадцатиричные цифры, закодированные четверками битов
· H — шестнадцатиричная строка, в которой сперва идут старшие шестнадцатиричные цифры, закодированные четверками битов
· i — целое значение со знаком (состоит по крайней мере из 32 бит, реальная длина определяется компилятором С)
· I — целое значение без знака (состоит по крайней мере из 32 бит, реальная длина определяется компилятором С)
· l — длинное целое со знаком (состоит ровно из 32 бит и может отличаться от типа данных long компилятора С)
· L — длинное целое без знака (состоит ровно из 32 бит и может отличаться от типа данных long компилятора С)
· n — короткое целое, используемое при сетевых обменах (старшие биты идут в конце, содержит ровно 16 бит)
· N — длинное целое, используемое при сетевых операциях (старшие биты идут в конце, содержит ровно 32 бит)
· p — указатель на строку, завершающуюся нуль-терминатором
· P — указатель на структуру (то есть строку фиксированной длины)
· q — 64-битное целое со знаком (доступно только если система поддерживает такие числа и Perl был собран с соответствующими ключами)
· Q — 64-битное целое без знака (доступно только если система поддерживает такие числа и Perl был собран с соответствующими ключами)
· s — короткое целое со знаком (в Perl состоит из 16 бит)
· S — короткое целое без знака (в Perl состоит из 16 бит)
· u — строка, закодированная по алгоритму uuencode
· v — короткое целое, используемое на комьютерах VAX (младшие биты идут в конце, содержит ровно 16 бит)
· V — длинное целое, используемое комьютерах VAX’ах (младшие биты идут в конце, содержит ровно 32 бит)
· w — целое, закодированное по стандарту BER (ISO Basic Encoding Rules). Байты представляют собой цифры числа, записанного в системе счисления с основанием 128. Количество байт — минимально необходимое для представления данного числа. Старший разряд идет первым. У всех цифр, кроме той, которая пересылается последней, 8-ой бит установлен в единицу.
· x — нулевой байт
· X — входной байт один к одному
· Z — текстовая строка, завершаемая нуль-терминатором и дополняемая двоичными нулями.
За символом (кроме символов a, A, b, B, h, H, P, Z) может следовать число, показывающее, сколько раз необходимо повторить соответствующий спецификатор. Для неопределенного числа повторений вместо конкретного числа можно использовать символ *. Например:
print pack ("ссс", 88, 89, 90);
XYZ
print pack ("с3", 65, 66, 67);
ABC
print pack ("с*", 68, 69, 70, 71);
DEFG
(Более детальные примеры могут быть найдены в документации Perl.)
Умножитель, следующий за символами a, A, Z, указывает на число байт, отводимое под соответствующее значение (то есть эти символы приводят к выборке одного значения из списка, несмотря на сопутствующий умножитель). При распаковке A удаляет хвостовые пробелы и нулевые байты, Z удаляет все после первого нулевого байта, a пересылает данные один к одному. Аналогично, символы b и B порождают строку из указанного числа битов, а h и H — строку, из указанного числа четверок битов.
Спецификаторы p и P сохраняются как значения указателей, и пользователь должен проследить, чтобы они не ссылались на временные переменные и соответствующие области памяти не изменялись до момента распаковки. Кроме того, повторитель, следующий за символом P, указывает количество байт, отведенное для структуры данных, а не число повторений символа P в формате. Если значение, на которое ссылаются указатели, является неопределенным (undef), подставляется пустой указатель.
Целые, упакованные в форматах i, I, l, L, s, S не являются переносимыми между процессорами и операционными системами, поскольку сохраняют порядок битов и байтов, естественный для соответствующего процессора (см. также далее раздел «vec — вектор целых значений без знака»). Так, процессоры Intel, Alpha и VAX являются «остроконечными» <$FТермины «тупоконечный» (big-endian) и «остроконечный» (little-endian), используемые здесь, заимствованы из «Путешествий Гулливера» Джонатана Свифта в той их части, где описывается обычай лилипутов есть куриные яйца с тупого или острого конца. Так, целое число 0x87654321 (десятичное 2271560481) записывается в виде набора байтов 0x12, 0x34, 0x56, 0x78 при «остроконечном» упорядочивании, и как 0x78, 0x56, 0x34, 0x12 при «тупоконечном» упорядочивании. Такая терминология (big-endian, little-endian, middle-endian) появилась еще в 70-х гг., когда Perl и в помине не было, и является вкладом американских программистов в международный компьютерный жаргон. — Примеч. перев. и ред.>, Motorola, m68k/88k, PPC, Sparc, HP PA, Power, Cray — «тупоконечными», а процессоры MIPS работают как «остроконечные» на компьютерах фирмы Digital и как «тупоконечные» на компьютерах Silicon Graphics. Для переносимого формата упаковки надо использовать спецификаторы n, N («тупоконечный» формат) и v, V («остроконечный» формат).
Perl использует данные с плавающей точкой двойной точности для внутренних вычислений. Поэтому значение, сперва упакованное, а затем распакованное с форматом f, может быть неидентичным самому себе. Кроме того, при упаковке Perl использует представление числа, естественное для данной машины — так, данные, упакованные на одном компьютере, не обязательно будут прочитаны правильно на другом компьютере.
pop — извлечение данных из массива
Функция pop возвращает последнее значение в массиве, укорачивая его на один элемент. Если не указан аргумент, используется массив @_:
pop массив
pop
Рассмотрим пример (обратите внимание, что первая команда создает массив @array, если он еще не существует):
push @array, 5;
print pop @array;
5
Функции POSIX
Лаборатория компьютерных систем Национального института стандартов и технологий (the National Institute of Standards and Technology Computer Systems Laboratory — NIST/CSL) в содружестве с другими организациями создала стандарт POSIX — Portable Operating System Interface. POSIX — это большая библиотека стандартизированных С-подобных функций, покрывающих стандартные потребности программирования, от базовых математических вычислений до продвинутой работы с файлами.
Модуль Perl POSIX предоставляет доступ к практически всем стандартным функциям POSIX версии 1003.1 — всего около 250 функций. Эти функции не являются встроенными подобно остальным функциям этой главы, однако, поскольку модуль POSIX обеспечивает программистам б’ольше возможностей, чем встроенные функции Perl, они описаны здесь. Модуль POSIX подключается с помощью команды use:
use POSIX; # добавить всю библиотеку POSIX
use POSIX qw/функция/ # добавить одну функцию
(Во втором варианте псевдокавычки qw/.../ (см. таблицу 2.3 в главе 2) помогают создать список из строк-имен функций, заключенных в кавычки.. Более подробно о команде use рассказывается в главе 13.)
Например, ниже вычисляется тангенс SYMBOL 112 \f "SymbolProp BT" \s 10/4 с помощью функции tan модуля POSIX (эта функция не имеет двойника среди встроенных функций Perl, однако для вычисления значения SYMBOL 112 \f "SymbolProp BT" \s 10/4 мы используем встроенную функцию Perl atan2):
use POSIX;
print POSIX::tan(atan2 (1, 1));
1
push — добавление данных к массиву
Функция push добавляет новое значение или список значений в конец массива и увеличивает его длину на число добавленных элементов:
push массив, список
Рассмотрим пример (обратите внимание, что команда push создает массив @array, если он еще не существует):
push @array, 5;
print pop @array;
5
rand — случайное число
Функция rand возвращает очередное «случайное» число, которое лежит в диапазоне от нуля до значения, заданного как параметр функции rand. Если не указан параметр, функция использует значение 1:
rand выражение
rand
При каждом обращении к функции возвращается новое значение. Для инициализации последовательности «случайных» чисел используется функция srand (см. ниже описание этой функции). Если функция rand вызвана без предшествующего вызова srand, в первый раз функция srand вызывается автоматически. Пример:
print rand, "\n", rand, "\n", rand, "\n";
0.6876220703125
0.55670166015625
0.678070068359375
reverse — переставить список в обратном порядке
Функция reverse берет список, заданный как входной параметр, переставляет его элементы в обратном порядке и возвращает в качестве результата получившийся список:
reverse список
Пример:
@array = (1, 2, 3);
print join(", ", reverse @array);
3, 2, 1
rindex — положение подстроки
Функция rindex возвращает последнюю позицию, на которой в строке расположена указанная пользователем подстрока. В отличие от функции index, она начинает поиск с конца строки, а не с начала:
rindex строка, подстрока, позиция
rindex строка, подстрока
Поиск подстроки начинается перед указанной позицией в направлении к началу строки. Если позиция не указана, поиск ведется с конца строки. Если подстрока не найдена, функция rindex возвращает значение -1 (или значение, на единицу меньше базового индекса массивов, хранимого в переменной $[, если оно не ноль). Пример:
$text = "Here is the text!";
print rindex $text, "text";
12
scalar — форсирование скалярного контекста
Функция scalar форсирует интерпретацию выражения, заданного в качестве ее аргумента. в скалярном контексте:
scalar выражение
Аналогичной функции, которая форсировала бы списковый контекст, в Perl нет. В следующем примере показана функция scalar за работой (обратите внимание, что возвращается последний элемент списка):
@array = (1, 2, 3);
print scalar @array;
3
shift — извлечение первого элемента массива
Функция shift извлекает первый элемент массива, возвращая его в качестве результат, сдвигает остальные элементы и уменьшает длину массива на единицу:
shift массив
shift
Если не указан аргумент, и функция работает в лексической области видимости подпрограммы и формата, используется массив @_. Если же вы находитесь в области видимости файла или в лексической области видимости конструкций eval, BEGIN, END или INIT, используется массив @ARGV.
sin — синус
Функция sin вычисляет синус аргумента, заданного в радианах. Если не указан аргумент, используется переменная $_:
sin выражение
sin
Чтобы вычислить арксинус, можно воспользоваться функцией POSIX::asin из пакета POSIX (см. ранее раздел «POSIX-функции»).
sort — сортировка списка
Функция sort сортирует список и возвращает результат:
sort подпрограмма список
sort {блок} список
sort список
Если не заданы ни подпрограмма, ни блок команд, то функция сортирует список в соответствии со стандартным порядком текстовых строк. Если указано имя подпрограммы, она должна возвращать целое число — либо меньшее, либо равное либо большее нуля, в зависимости от результата сравнения двух переданных ей элементов списка. Вы можете также задать блок команд в качестве встраиваемой по месту подпрограммы. Рассмотрим несколько примеров:
@array = (’z’, ’b’, ’a’, ’x’, ’y’, ’c’);
print join (", ", sort @array) . "\n";
a, b, c, x, y, z
print join (", ", sort {$a cmp $b} @array) . "\n";
a, b, c, x, y, z
print join (", ", sort {$b cmp $a} @array) . "\n";
z, y, x, c, b, a
@array = (1, 5, 6, 7, 3, 2);
print join (", ", sort {$a <=> $b} @array) . "\n";
1, 2, 3, 5, 6, 7
print join (", ", sort {$b <=> $a} @array) . "\n";
7, 6, 5, 3, 2, 1
splice — замена среза массива
Функция splice удаляет из массива последовательно расположенные элементы и, если это требуется, добавляет вместо них новые:
splice массив, смещение, длина, список
splice массив, смещение, длина
splice массив, смещение
Параметр смещение задает индекс первого удаляемого элемента массива, параметр длина — число удаляемых элементов. Если параметр длина не задан, удаляются все элементы до конца массива. Если дополнительно задан список элементов, после операции удаления эти элементы добавляются в массив начиная с индекса, обозначенного параметром смещение, сдвигая имеющиеся в массиве элементы и увеличивая его длину.
Результат работы функции зависит от контекста. В списковом контексте возвращается список удаленных элементов. В скалярном контексте возвращается последний удаленный элемент. Если ни один элемент не удален, возвращается «неопределенное» значение undef.
В следующем примере к массиву добавляется новый элемент "three" после того, как в него записываются элементы "one" и "two":
@array = ("one", "two");
splice (@array, 2, 0, "three");
print join (", ", @array);
one, two, three
split — разбивка строки на список строк
Функция split превращает строку в массив строк, разбивая ее в позициях, соответствующих заданному шаблону:
split /шаблон/, текст, лимит
split /шаблон/, текст
split /шаблон/
split
Если шаблон (регулярное выражение) задан, Perl рассматривает фрагменты текста, сопоставляемые с шаблоном, как разделители полей. Cами разделители, как правило, исключаются из результата. Если текст не задан, используется специальная переменная Perl $_. Если не задан шаблон, строка $_ разбивается по «пробельным символам», причем начальные «пробельные символы» игнорируются. Пример:
@array = split /[,\s]\s*/, "Hello, my friends!";
print join ("/ ", @array);
Hello/my/friends!
Если параметр лимит задан и является положительным числом, функция останавливается, когда достигнуто указанное количество фрагментов (в этом случае последняя строка списка содержит необработанный «хвост»). Если параметр лимит не задан или равен нулю, то это соответствует режиму по умолчанию, когда разбиение ведется до конца строки и концевые пустые строки не включаются в список. Если же параметр лимит — отрицательное число, концевые пустые строки входят в результат.
Если, однако, используется присвоение списком, Perl будет разбивать строку на фрагменты до тех пор, пока не превысит число имеющихся в его распоряжении переменных. Например, в следующем случае неявно подразумевается, что параметр лимит равен четырем:
($login, $password, $remainder) = split /:/, $text
(Это позволяет экономить время выполнения для приложений, у которых оно критично.)
Обычно разделитель не включается в строки, из которых составлен список. Однако, если шаблон содержит фрагменты, заключенные в круглые скобки, то соответствующие подстроки добавляются к разбиению:
print join ("|", split(/\s*[,-]\s*/,"1 - 10, 20"));
1|10|20
print join ("|", split(/\s*([,-])\s*/,"1 - 10, 20"));
1|-|10|,|20
Как правило, начальные пустые строки включаются в список, а конечные — нет. Если для параметра лимит задано отрицательное значение, концевые строки также входят в результат. Если в качестве шаблона задано значение ’ ’, производится разбиение по границам «пробельных символов», причем ведущие «пробельные символы» игнорируются. Похожий на него шаблон / / разобьет входной текст по всем пробелам, породив массу пустых строк. Шаблон /\s+/ практически аналогичен шаблону ’ ’ за тем исключением, что при наличии ведущих пробелов выходной список будет начинаться с пустой строки.
Шаблоны, сопоставляемые пустой строке (//, /\s*/, и так далее) также специальным образом обрабатываются функцией split— они разбивают входную строку на отдельные символы:
print join ("-", split(//,"Hello"));
H-e-l-l-o
В списковом контексте функция split возвращает список строк, полученных в результате разбиения. В скалярном контексте она возвращает число разбиений, а результат разбиения заносится в массив @_. Можно принудительно заполнить массива @_ результатом разбиения также и в списковом контексте, если ограничить шаблон вопросительными знаками. Такое неявное заполнение массива @_ не приветствуется в Perl, так как конфликтует с передачей параметров подпрограммам.
В качестве шаблона можно задавать выражение, вычисляемое во время работы программы:
$variable1 = "\s*[+*/=-]";
@array = split /$variable1/, "2 + 2 = 4";
print join (", ", @array);
2, 2, 4
Если выражение должно компилироваться в процессе выполнения сценария только один раз, задайте модификатор o (см. главу 6 и описание операторов m/.../ и s/.../.../):
$variable1 = "\s*[+*/=-]";
@array = split /$variable1/o, "2 + 2 = 4";
print join (", ", @array);
2, 2, 4
Как и в случае операторов m/.../, s/.../.../ и tr/.../.../, для функции split в качестве ограничителя шаблона нет необходимости использовать косую черту.
sprintf — форматирование строки
Функция sprintf создает выходную строку, производя для заданного списка значений процедуру интерполяции в соответствии с указанными пользователем спецификаторами формата:
sprintf формат, список
В общем случае каждому элементу списка соответствует свой спецификатор формата в строке формат. Существуют следующие спецификаторы:
· %% — знак процента
· %c — символ с заданным кодом
· %d — целое со знаком в десятичной записи
· %e — число с плавающей точкой, мантиссой и порядком
· %E — то же самое, что %e, но для обозначения порядка используется `E’, а не `e’
· %f — число с плавающей точкой в фиксированном формате без указания порядка
· %g — число с плавающей точкой либо в формате %f, либо в формате %e (в зависимости от того, можно ли корректно записать значения числа в формате %f)
· %G — то же самое, что %g, но для обозначения порядка используется `E’, а не `e’
· %n — запоминает в следующей переменной (элементе списка) число уже выведенных символов
· %o — целое без знака в восьмиричной записи
· %p — указатель (адрес значения как шестнадцатиричное число)
· %s — строка
· %u — целое без знака в десятичной записи
· %x — целое без знака в шестнадцатиричной записи
· %X — то же самое, что %x, но с заглавными латинскими буквами в качестве шестнадцатиричных чисел.
Для совместимости с ранними версиями, Perl использует также:
· %D — то же самое, что и %ld
· %F — то же самое, что и %lf
· %i — то же самое, что и %d
· %O — то же самое, что и %lo
· %U — то же самое, что и %lu
Кроме того, между символом процента и буквой, задающей тип формата, можно использовать следующие дополнительные спецификаторы:
· - — выравнивать по левому краю поля
· # — добавить префикс '0' для восьмиричного и префикс '0x' для шестнадцатиричного числа, если оно отлично от нуля
· + — для положительного числа добавить префикс `+’
· пробел — для положительного числа добавить пробел в качестве префикса
· 0 — использовать нули, а не пробелы для выравнивания по правому краю
· h — интерпретировать целое значение как тип short или unsigned short языка C
· l — интерпретировать целое значение как тип long или unsigned long языка C
· V — интерпретировать целое значение как стандартный целочисленный тип Perl (не имеет аналогов в языке C)
· число — минимальный размер поля
· .число — для чисел с плавающей точкой задает число знаков после десятичной точки; для целых чисел задает минимальное число разрядов; для строк задает максимальную длину строки.
(Для одного базового спецификатора можно указывать несколько дополнительных.)
Если вместо числа указана звездочка *, то в качестве числа будет использовано очередное значение из входного списка данных. Оно должно быть целым положительным числом. Исключением является минимальный размер поля: для него отрицательное значение интерпретируется как дополнительный спецификатор -, то есть как выравнивание по левому краю поля.
Вот несколько примеров (обратите внимание, что в первом примере число округляется):
$value = 1234.56789;
print sprintf "X=%.4f\n", $value
X=1234.5679
print sprintf "Y=%.5f\n", $value
Y=1234.56789
print sprintf "Z=%6.6f\n", $value
Z=1234.567890
print sprintf "W=%+.4e\n", $value
W=+1.2346e+003
sqrt — квадратный корень
Функция sqrt вычисляет квадратный корень своего аргумента. Если не указан аргумент, используется переменная $_:
sqrt выражение
sqrt
Пример:
print sqrt 144;
12
srand — инициатор генератора случайных чисел
Функция srand инициализирует работу генератора «случайных» чисел. Если указывать ей один и тот же аргумент, функция rand будет генерировать одни и те же последовательности. Если аргумент не указан, используется значение, основанное на текущем времени и идентификаторе процесса:
srand выражение
srand
substr — подстрока текстовой строки
Функция substr возвращает подстроку текстовой строки, переданной ей в качестве аргумента:
substr текст, смещение, длина, замена
substr текст, смещение, длина
substr текст, смещение
Подстрока начинается с символа, имеющего заданное смещение от начала строки. Если смещение отрицательно, подстрока начинается с конца строки и двигается от конца к началу. Если не задана длина, возвращается весь текст до конца исходной строки. Если длина отрицательна, указанное количество символов вычитается из длины оставшегося до конца строки текста. Если задан параметр замена, то в качестве текста должно быть указано «левое значение» (то есть аргумент, имеющий право находиться в левой части оператора присваивания), а функция substr не просто вернет подстроку, но и заменит в исходном тексте ее на новый фрагмент. Примеры:
$text = "Here is the text.";
print substr ($text, 12) . "\n";
text.
print substr ($text, 12, 4) . "\n";
text
print substr ($text, 12, 4, "word") . "\n";
print $text;
text
Here is the word.
time — время в секундах с 1 января 1970 года
Функция time количество секунд, прошедших с момента некоторого ключевого события:
time
Большинство интерпретаторов Perl используют в качестве «ключевого момента» 00:00:00 1-го января 1970 года единого временного календаря (то есть момент, с которого отсчитывает время операционная система Unix). Однако, например, для MacOs «ключевым моментом» является 00:00:00 1-го января 1904 года<$FКстати, значения, генерируемые mktime на машине, работающей под управлением Windows, неправильно интерпретируются в Unix и наоборот. При этом, однако, разные варианты Unix (Solaris, FreeBSD и Linux) дают вполне переносимые результаты. — Примеч. ред.>.
uc — преобразование букв к верхнему регистру
Функция uc возвращает строку, переданную ей в качестве параметра, преобразованной к нижнему регистру, то есть заменяя в выходной строке строчные буквы на заглавные. Если аргумент опущен, используется переменная $_:
uc выражение
uc
Пример:
print uc "hello!";
HELLO!
ucfirst — преобразование первой буквы к верхнему регистру
Функция ucfirst возвращает исходную строку, в которой первая буква (если это буква) преобразована к верхнему регистру (то есть строчная буква заменяется на заглавную). Если у функции не указан аргумент, используется переменная $_:
ucfirst выражение
ucfirst
Пример:
print ucfirst "hello!";
Hello!
unpack — упаковка значений
Функция unpack получает бинарную структуру, упакованную функцией pack (см. выше), а возвращает список распакованных значений:
unpack шаблон, выражение
В качестве шаблона используется строка, задававшаяся при вызове функции pack. В качестве значения возвращается контрольная сумма. Например:
$string = pack ("ссс", 88, 89, 90);
print join(", ", unpack " ссс ",$string);
88, 89, 90
В следующем мы распаковываем шестнадцатиричное значение, упакованное функцией vec (см. ее описание ниже), в строку, состоящую из нулей и единиц:
vec ($data, 0, 32) = 0x11;
$bitstring = unpack("B*", $data);
print $bitstring;
00000000000000000000000000010001
unshift — добавление первого элемента в массив
Функция unshift добавляет в начало массива элемент или список, сдвигая остальные элементы и увеличивая длину массива на число добавленных элементов:
unshift массив, список
Пример:
@array = (4, 5, 6);
unshift @array, 1, 2, 3;
print join(", ", @array);
1, 2, 3, 4, 5, 6
values — список значений хеша
В списковом контексте функция values возвращает список, состоящий из всех значений (не ключей!), содержащихся в хеше. В скалярном контексте она возвращает число — количество значений:
values хеш
Пример:
$hash{sandwich} = ’ham and cheese’;
$hash{drink} = ’diet cola’;
foreach $value (values %hash) {
print "$value\n";
}
diet cola
ham and cheese
vec — вектор целых значений без знака
Функция vec рассматривает строку, переданную ей в качестве параметра, как одномерный битовый массив (называемый вектором), составленный из расположенных друг за другом целых без знака. В качестве результата возвращается битовое поле нужной длины, начинающееся с указанного смещения:
vec выражение, смещение, длина-поля
Параметр длина-поля указывает число битов, зарезервированное под каждый элемент вектора. Он должен быть степенью двойки от 1 до 32. Если поле выходит за рамки строки, оно дополняется нулями. Пример:
$text = "ABCD";
print vec($text,0,8), ’\n’; # letter A
print vec($text,1,8), ’\n’; # letter B
print vec($text,2,8), ’\n’; # letter C
print vec($text,3,8), ’\n’; # letter D
print vec($text,4,8), ’\n’; # выход за границу строки
65
66
67
68
0
Вы также можете присваивать новые значения конструкции vec. В этом случае, чтобы отделить список параметров от операции присваивания, параметры функции vec должны быть заключены в круглые скобки. Пример:
$text = "ABCD";
vec($text, 2, 8) = 65;
print "$text\n";
ABAD
Присвоение конструкции vec(...) нового значения может не только модифицировать содержимое строки, но и изменять ее размер:
$text = "ABCD";
vec($text, 4, 8) = 69; print "$text\n";
vec($text, 6, 8) = ord "F"; print "$text\n";
ABCDE
ABCDE F
Порядок следования битов зависит от того, как организована память компьютера. Следующий результат получен для платформы Win32 (процессор Intel):
$text = "ABCD";
for $loop_index (0..7) {
print vec($text, $loop_index, 4), "/";
}
1/4/2/4/3/4/4/4
В этом случае адреса памяти возрастают справа налево:
ind(8) |
3 |
2 |
1 |
0 |
|
|||||
ind(4) |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
|
char |
"D" |
"C" |
"B" |
"A" |
| |||||
hex(8) |
0x44 |
0x43 |
0x42 |
0x41 |
| |||||
hex(4) |
4 |
4 |
4 |
3 |
4 |
2 |
4 |
1 |
|
|
bin |
0100 |
0100 | 0100 | 0011 | 0100 | 0010 | 0100 |
0001 |
|
Обратите внимание, что, если вы рассматриваете поля, состоящие из 8-ми бит, то при работе со строками порядок организации памяти не существенен. Это видно из следующего рисунка, где адреса памяти возрастают справа налево (хотя, например, на уровне двухбайтовых слов разница будет существенной):
ind(8) |
0 |
1 |
2 |
3 |
|
|||||
ind(4) |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
|
|
char |
"A" |
"B" |
"C" |
"D" |
| |||||
hex(8) |
0x41 |
0x42 |
0x43 |
0x44 |
| |||||
hex(4) |
4 |
1 |
4 |
2 |
4 |
3 |
4 |
4 |
|
|
bin |
0100 |
0001 | 0100 | 0010 | 0100 | 0011 | 0100 |
0100 |
|
Следующий пример показывает, как распечатать побитно (то есть в виде числа с основанием два) шестнадцатиричное значение:
$data = "";
vec($data,0,8) = 0xB;
print vec ($data, 3,1);
print vec ($data, 2,1);
print vec ($data, 1,1);
print vec ($data, 0,1);
1011
(Обратите внимание, что до того как выполняется присвоение конструкции vec(...), в следующей строке сценария, должна быть инициализирована переменная $data. В отличие от ссылок, на функцию vec не распространяется процесс автооживления (autovivification), описанный в главе 8.)
Для той же цели (то есть чтобы преобразовать битовый вектор в строку из нулей и единиц) более практично использовать функцию unpack:
$text = "ABCD";
@bits_decomposed = split(//, unpack("b*", $text));
$bits_printed = unpack "B*", $text;
print @bits_decomposed . "\n";
print "$bits_printed\n";
10000010010000101100001000100010
01000001010000100100001101000100
В первом случае мы распаковываем биты, начиная с самого младшего и кончая самым страшим. Во втором — порядок распаковки прямо противоположный. Это дает двоичное число в привычном виде, но может оказаться не самой удобной формой, если предполагается дополнительный анализ результата.
[A1]Добавлено