≪
≫

Возвращение пустых элементов

Если между совпадениями для первого операнда нет текста (совпадения идут подряд), то на соответствующих местах возвращаются пустые элементы. Оператор

print join split ‘=’, ‘a=b==c’;

напечатает

a-b--c

В этом случае пустые элементы, расположенные в конце текста, не возвращаются. Например, оператор

print join ‘-'.split *=’, 1===a=b==c===’;

напечатает

—a-b—с

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

print join split , ‘===a-b--c===' r -1; напечатает

—-a-b--c-—

Число -1 здесь эквивалентно бесконечно большому положительному числу.

Иногда бывает нужно получить только непустые элементы разбиения текста. Для этого перед оператором split можно поставить вызов функции grep с аргументом length'.

print grep { length } split *===a=b==c===', -1;

или вместо length можно подставить само возвращаемое в $_ split значение:

print grep split *=’, u---a-b--c--=’, -1;

Напечатается просто abc. К каждому элементу списка, возвращаемому оператором split, будет применена функция length. И если результат будет равен нулю, то этот элемент будет удален из данного списка.

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

print join split /(?=w)/t “abed”;

напечатает a-b-c-d, хотя перед буквой а тоже было совпадение.

Обращаю ваше внимание, что оператор

split /"/пі, $text;

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

Отсутствие побочных эффектов у оператора split

Оператор split не имеет побочных эффектов: он не изменяет регулярное выражение по умолчанию, не устанавливает специальные переменные 57, $ 5

занный с регулярными выражениями: при использовании оператора split в скалярном контексте он записывает возвращаемый результат в массив который также используется для передачи параметров функциям. При применении директивы use warnings или параметра -и при запуске Perl выдается соответствующее предупреждение:

#!/usr/bin/perl -w

use strict;

scalar split /(?=w)/, “abed”; print

Напечатается

Use of implicit split to is deprecated at z.pl line 4, abed

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

split /(w)(?{ print “=$1-’ })/, “abed”;

напечатает текст

-a=-b-=c=-d-

Захватывающие скобки в первом операнде оператора split

Если в первом операнде оператора split имеются захватывающие скобки, то фрагменты текста, которые они захватили, также вставляютя в результирующий список между фрагментами текста, на которые разбился заданный текст. Эти фрагменты, совпавшие с захватывающими скобками, не учитываются в общем числе возвращаемых фрагментов, т.к. третий операнд определяет не число возвращаемых фрагментов, а количество фрагментов, на которые разбивается исходный текст. Если какая-либо пара захватывающих скобок не участвовала в совпадении, то она возвращает значение undef. Пример:

print join , split /(d+)/, 'a12b23c34d45e56’, 3;

Напечатается

a-12-b-23-c34d45e56

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

Вот еще пример - HTML-текст разбивается на текст вне тегов и при этом возвращаются все теги:

$_=«EOD;

<Ь>жирный текст обычный текст <і>курсив

заголовок

обычный текст

EOD print join split /(<[">]+>)/;

Будет напечатано:

-<Ь>-жирный текст--обычный текст -<і>-курсив--

-

- заголовок -

-обычный текст

Оператор split обычно используется при получении данных от форм HTML. Ниже приведен пример стандартной программы, которая принимает формы, отправленные по методу GET и POST, и записывает имена и значения переменных в ассоциативный хэш contents:

if ($ENV{‘REQUEST-METHOD’} eq ‘POST’)

# Принимаем данные по методу POST

{ # Читаем переданные формой данные

read(STDIN, $buffer, $ENV{‘CONTENT-LENGTH'});

и Разбиваем их на пары «имя-значение»

@pairs=split(/&/, Sbuffer);

foreach $pair (@pairs)

{ # Каждую пару разбиваем на «имя» и «значение»

($name,$value)=split(/=/, $pair);

Н Заменяем плюсы на пробелы (браузеры кодируют пробелы плюсами) $value =~ tr/+/ /;

ії Заменяем 16-ные байты их значениями

$value =~ s/%([a-fA-F0-9][a-fA-f0-9])/pack("C",hex($1 ))/eg:

# Записываем результат в хеш

$content s{$name}=$value;

}

} elsif ($ENV{'REQUEST-METHOD'} eq ‘GET’)

й Принимаем данные по методу GET

{ @pairs=split(/&/, $ENV{QUERY_STRING});

foreach $pair (@pairs)

{ ($name,$value)=split(/=/tSpain);

$value =~ tr/+/ /;

$value =* s/%([a-fA-FO-9][a-fA-fO-9])/pack(“C,’1 hex($1))/eg;

$contents{$name}=$value;

}

}

print “Content-Type: text/html ";

print ‘OK’;

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

Функция grep

Функция grep является мощным инструментом для создания из списков подсписков по определенным критериям. Эта мощь обусловлена тем фактом, что данная функция может использовать регулярные выражения. Модификаторы этого регулярного выражения те же, что и у оператора split. Функция grep имеет две разновидности вызова:

grep { блок команд } список

и grep выражение, список

Эта функция в неявном цикле по всем элементам списка для каждого из них выполняет заданный блок команд или выражение. Причем при каждой итерации цикла во время выполнения блока команд или выражения переменная $_ является синонимом очередного элемента списка. В частности, присвоение этой переменной значения повлечет присвоение этого же значения соответствующему элементу списка. Функция в качестве результата возвращает подсписок, для которых вычисленное значение выражения/блока команд является истиной (отлично от нуля, пустой строки и т. д.). Например, код

open F, 'prog.pl';

print grep { !/"#rs*$/m } ; close F;

распечатает все строки файла prog.pl, которые не начинаются с символа # и не содержат одни лишь пробельные символы.

 
Посмотреть оригинал