Захватывающие скобки в первом операнде оператора split
Если в первом операнде оператора split имеются захватывающие скобки, то фрагменты текста, которые они захватили, также вставляютя в результирующий список между фрагментами текста, на которые разбился заданный текст. Эти фрагменты, совпавшие с захватывающими скобками, не учитываются в общем числе возвращаемых фрагментов, т.к. третий операнд определяет не число возвращаемых фрагментов, а количество фрагментов, на которые разбивается исходный текст. Если какая-либо пара захватывающих скобок не участвовала в совпадении, то она возвращает значение undef.
Пример:
print join '-', split /(\d+)/, 'a12b23c34d45e56', 3;
Напечатается
a-12-b-23-c34d45e56
т.е. числа, по которым разбивался текст, заносятся в результат, чередуясь с самими фрагментами, на которые был разбит исходный тест. Текст был разбит на три части.
Вот еще пример - HTML-текст разбивается на текст вне тегов и при этом возвращаются все теги:
$_=<<EOD; <b>жирный текст</b> обычный текст <i>курсив</i> <h1> заголовок </h1> обычный текст EOD
print join '-', split /(<[^>]+>)/;
Будет напечатано:
-<b>-жирный текст-</b>- обычный текст -<i>-курсив-</i>- -<h1>- заголовок -</h1>- обычный текст
Оператор split обычно используется при получении данных от форм HTML. Ниже приведен пример стандартной программы, которая принимает формы, отправленные по методу GET и POST, и записывает имена и значения переменных в ассоциативный хеш contents:
if ($ENV{'REQUEST_METHOD'} eq 'POST') # Принимаем данные по методу POST { # Читаем переданные формой данные read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); # Разбиваем их на пары имя=значение @pairs=split(/&/, $buffer); 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; # Записываем результат в хеш $contents{$name}=$value; } } elsif ($ENV{'REQUEST_METHOD'} eq 'GET') # Принимаем данные по методу GET { @pairs=split(/&/, $ENV{QUERY_STRING}); foreach $pair (@pairs) { ($name,$value)=split(/=/,$pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-f0-9])/pack("C",hex($1))/eg; $contents{$name}=$value; } }
print "Content-Type: text/html\n\n"; print '<html><body>OK</body></html>';
Эту программу можно сократить, т.к. в цикле производятся те же самые операции.