Регулярные выражения Perl и их применение


         

Компиляция и кэширование регулярных выражений


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

При компиляции сначала происходит обработка литералов регулярного выражения.

  1. Отыскивается завершающий ограничитель регулярного выражения и читаются модификаторы всего регулярного выражения, которые стоят за этим ограничителем. Наличие модифиатора x учитывается при обработке литерала регулярного выражения.
  2. Если регулярное выражение имеет интерполируемые переменные, то вместо них подставляется их значение. При этом учитывается, что последовательности символов $|, $), … не являются переменными и не интерполируются.
  3. Далее обрабатываются конструкции изменения регистра /U, /l, … а также конструкции /Q…/E, но в тех частях регулярного выражения, которые получились от интерполяции переменных, эти конструкции не распознаются и не обрабатываются.

Потом, если не было замечено ошибок на шагах 1-3, регулярное выражение переводится в свою внутреннюю форму, готовую к применению механизмом регулярных выражений.

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

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

Отказ от перекомпиляции регулярного выражения дает очень существенную экономию времени, поэтому используйте объекты регулярных выражений qr/…/. Они содержат уже откомпилированное и готовое к использованию регулярное выражение, представляя собой как бы автономный кэш регулярного выражения.

Если после интерполяции переменных регулярное выражение имеет пустое содержание, то вместо него применяется последнее успешно совпавшее регулярное выражение. Это можно использовать для оптимизации времени работы программы. Приведу такой пример:

my $a='abc'; my $b='cde'; my $re='(\w)'; $a =~ /$re/; print "$1\n"; $b =~ //; print $1;



Содержание  Назад  Вперед





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