Опубликован: 18.06.2007 | Доступ: свободный | Студентов: 1354 / 35 | Оценка: 4.14 / 3.29 | Длительность: 12:44:00
ISBN: 978-5-94774-604-4
Лекция 14:

Оператор split и функция grep

< Лекция 13 || Лекция 14: 123

14.1.5. Захватывающие скобки в первом операнде оператора 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>';

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

14.1. Функция grep

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

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

и

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

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

open F, 'prog.pl';
print grep { !/^#|^\s*$/m } <F>;
close F;

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

< Лекция 13 || Лекция 14: 123
Константин Бражников
Константин Бражников
Россия
Mike .
Mike .
Россия