Spec-Zone.ru › Perl 5.32

perlreapi

СОДЕРЖАНИЕ

  • ИМЯ
  • ОПИСАНИЕ
  • Обработчики
    • comp
    • exec
    • intuit
    • checkstr
    • free
    • Обработчики захваченных групп по номеру
      • numbered_buff_FETCH
      • numbered_buff_STORE
      • numbered_buff_LENGTH
    • Обработчики захваченных групп по имени
      • named_buff
      • named_buff_iter
    • qr_package
    • dupe
    • op_comp
  • Структура REGEXP
    • engine
    • mother_re
    • extflags
    • minlen minlenret
    • gofs
    • substrs
    • nparens, lastparen и lastcloseparen
    • intflags
    • pprivate
    • offs
    • precomp prelen
    • paren_names
    • substrs
    • subbeg sublen saved_copy suboffset subcoffset
    • wrapped wraplen
    • seen_evals
    • refcnt
  • ИСТОРИЯ
  • АВТОРЫ
  • ЛИЦЕНЗИЯ

ИМЯ

perlreapi - интерфейс плагина Perl для регулярных выражений

ОПИСАНИЕ

Начиная с Perl 5.9.5 появился новый интерфейс для подключения и использования движков регулярных выражений, отличных от стандартного.

Каждый движок должен предоставить доступ к постоянной структуре следующего формата:

typedef struct regexp_engine {
    REGEXP* (*comp) (pTHX_
                     const SV * const pattern, const U32 flags);
    I32     (*exec) (pTHX_
                     REGEXP * const rx,
                     char* stringarg,
                     char* strend, char* strbeg,
                     SSize_t minend, SV* sv,
                     void* data, U32 flags);
    char*   (*intuit) (pTHX_
                       REGEXP * const rx, SV *sv,
                       const char * const strbeg,
                       char *strpos, char *strend, U32 flags,
                       struct re_scream_pos_data_s *data);
    SV*     (*checkstr) (pTHX_ REGEXP * const rx);
    void    (*free) (pTHX_ REGEXP * const rx);
    void    (*numbered_buff_FETCH) (pTHX_
                                    REGEXP * const rx,
                                    const I32 paren,
                                    SV * const sv);
    void    (*numbered_buff_STORE) (pTHX_
                                    REGEXP * const rx,
                                    const I32 paren,
                                    SV const * const value);
    I32     (*numbered_buff_LENGTH) (pTHX_
                                     REGEXP * const rx,
                                     const SV * const sv,
                                     const I32 paren);
    SV*     (*named_buff) (pTHX_
                           REGEXP * const rx,
                           SV * const key,
                           SV * const value,
                           U32 flags);
    SV*     (*named_buff_iter) (pTHX_
                                REGEXP * const rx,
                                const SV * const lastkey,
                                const U32 flags);
    SV*     (*qr_package)(pTHX_ REGEXP * const rx);
#ifdef USE_ITHREADS
    void*   (*dupe) (pTHX_ REGEXP * const rx, CLONE_PARAMS *param);
#endif
    REGEXP* (*op_comp) (...);

При компиляции regexp поле engine устанавливается на указанную структуру, чтобы Perl мог найти необходимые функции.

Для установки нового обработчика regexp поле $^H{regcomp} устанавливается на целое число, которое (при соответствующем преобразовании) указывает на одну из этих структур. При компиляции вызывается метод comp, и ожидается, что поле engine структуры regexp будет указывать на ту же структуру.

Символ pTHX_ в определении — макрос, используемый Perl для потоков, чтобы передавать дополнительный аргумент в процедуру, содержащую указатель на интерпретатор, выполняющий регулярное выражение. При использовании потоков все функции получают дополнительный аргумент.

Обработчики

comp

REGEXP* comp(pTHX_ const SV * const pattern, const U32 flags);

Скомпилировать шаблон, хранящийся в pattern, используя заданные flags, и вернуть указатель на подготовленную структуру REGEXP, которая может выполнять поиск соответствий. См. "Структура REGEXP" ниже для описания отдельных полей структуры REGEXP.

Параметр pattern — скаляр, который использовался в качестве шаблона. Предыдущие версии Perl передавали два char*, указывающие начало и конец строкового представления шаблона; следующий фрагмент кода может быть использован для получения старых параметров:

STRLEN plen;
char*  exp = SvPV(pattern, plen);
char* xend = exp + plen;

Так как в качестве шаблона может передаваться любой скаляр, возможно реализовать движок, который что-то делает с массивом ("ook" =~ [ qw/ eek hlagh / ]) или со нестроковым представлением скомпилированного регулярного выражения ("ook" =~ qr/eek/). Собственный движок Perl всегда строит всё с помощью фрагмента кода выше, но это не означает, что другие движки должны это делать.

Параметр flags — битовая маска, указывающая, какие из msixpn флагов были установлены при компиляции регулярного выражения. Также содержит дополнительную информацию, например, если use locale активен.

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

К моменту вызова обработчика comp некоторые из этих флагов уже повлияли (указано в соответствующих местах). Однако большинство их эффектов происходит после вызова обработчика comp в функциях, которые считывают поле rx->extflags, которое оно заполняет.

В целом флаги должны сохраняться в rx->extflags после компиляции, хотя движок регулярных выражений может захотеть добавить или удалить некоторые из них, чтобы вызвать или отключить определённое поведение в Perl. Флаги и любое дополнительное поведение, которое они вызывают, описаны ниже:

Модификаторы шаблона:

/m - RXf_PMf_MULTILINE

Если он присутствует в rx->extflags, он будет передан в Perl_fbm_instr функцией pp_split, которая будет обрабатывать строку-субъект как многострочную строку.

/s - RXf_PMf_SINGLELINE
/i - RXf_PMf_FOLD
/x - RXf_PMf_EXTENDED

Если он присутствует в регулярном выражении, "#" комментарии будут обрабатываться иначе токенизатором в некоторых случаях.

TODO: Документировать эти случаи.

/p - RXf_PMf_KEEPCOPY

TODO: Документировать это

Набор символов

Правила набора символов определяются перечислением, которое содержится в этом поле. Это ещё экспериментальная функция и может быть изменена, но текущий интерфейс возвращает правила с помощью встроенной функции get_regex_charset(const U32 flags). Единственное в настоящее время документированное значение, возвращаемое ею, — REGEX_LOCALE_CHARSET, которое устанавливается, если use locale активен. Если он присутствует в rx->extflags, split будет использовать зависимую от локали локализацию пробелов, если RXf_SKIPWHITE или RXf_WHITE активны. Пробелы ASCII определяются согласно isSPACE и внутренним макросам is_utf8_space в UTF-8 и isSPACE_LC в use locale.

Дополнительные флаги:

RXf_SPLIT

Этот флаг был удалён в Perl 5.18.0. split ' ' теперь обрабатывается в анализаторе. RXf_SPLIT всё ещё определён, поэтому можно проверить его. Вот как он работал раньше:

Если split вызывается как split ' ' или без аргументов (что фактически означает split(' ', $_), см. split), Perl установит этот флаг. Движок регулярных выражений может затем проверить его и установить флаги SKIPWHITE и WHITE. Для этого движок Perl делает:

if (flags & RXf_SPLIT && r->prelen == 1 && r->precomp[0] == ' ')
    r->extflags |= (RXf_SKIPWHITE|RXf_WHITE);

Эти флаги могут быть установлены во время компиляции для включения оптимизаций в операторе split.

RXf_SKIPWHITE

Этот флаг был удален в Perl 5.18.0. Он все еще определен, поэтому его можно установить, но это не повлияет на результат. Вот как он работал раньше:

Если флаг присутствует в rx->extflags, split удалит пробелы из начала строки-субъекта перед её обработкой. Что считается пробелом, зависит от того, является ли субъект UTF-8 строкой, и установлен ли флаг RXf_PMf_LOCALE.

Если RXf_WHITE установлен в дополнение к этому флагу, split будет вести себя как split " " в движке Perl.

RXf_START_ONLY

Указывает оператору split разделять целевую строку на новые строки (\n) без вызова движка регулярных выражений.

Движок Perl устанавливает этот флаг, если шаблон является /^/ (plen == 1 && *exp == '^'), даже в условиях /^/s; см. split. Конечно, другой движок регулярных выражений может захотеть использовать те же оптимизации с другим синтаксисом.

RXf_WHITE

Указывает оператору split разделять целевую строку на пробелы без вызова движка регулярных выражений. Определение пробелов зависит от того, является ли целевая строка UTF-8 строкой и установлен ли RXf_PMf_LOCALE.

Движок Perl устанавливает этот флаг, если шаблон равен \s+.

RXf_NULL

Указывает оператору split разделять целевую строку на символы. Определение символов зависит от того, является ли целевая строка UTF-8 строкой.

Движок Perl устанавливает этот флаг на пустые шаблоны, эта оптимизация делает split // намного быстрее, чем это было бы в противном случае. Он даже быстрее, чем unpack.

RXf_NO_INPLACE_SUBST

Добавлен в Perl 5.18.0, этот флаг указывает, что регулярное выражение может выполнить операцию, которая помешает выполнению подстановки на месте. Например, он может содержать обратные ссылки, или присваивать значения не-магическим переменным (например, $REGMARK и $REGERROR) во время поиска совпадений. s/// пропустит определённые оптимизации, когда этот флаг установлен.

exec

I32 exec(pTHX_ REGEXP * const rx,
         char *stringarg, char* strend, char* strbeg,
         SSize_t minend, SV* sv,
         void* data, U32 flags);

Выполнение регулярного выражения. Аргументы:

rx

Регулярное выражение для выполнения.

sv

Это SV, которое должно быть сопоставлено. Обратите внимание, что фактический массив символов для сопоставления предоставляется аргументами, описанными ниже; SV используется только для определения UTF8-ности, pos() и т. д.

strbeg

Указатель на физическое начало строки.

strend

Указатель на символ, следующий за физическим концом строки (т. е. \0, если таковой имеется).

stringarg

Указатель на позицию в строке, с которой должно начинаться сопоставление; она может не совпадать с strbeg (например, в последующей итерации /.../g).

minend

Минимальная длина строки (измеряемая в байтах с stringarg), которая должна быть сопоставлена; если движок достигнет конца сопоставления, но не достигнет этой позиции в строке, произойдёт ошибка.

data

Данные оптимизации; могут изменяться.

flags

Флаги оптимизации; могут изменяться.

intuit

char* intuit(pTHX_
            REGEXP * const rx,
            SV *sv,
            const char * const strbeg,
            char *strpos,
            char *strend,
            const U32 flags,
            struct re_scream_pos_data_s *data);

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

Аргументы:

rx:     the regex to match against
sv:     the SV being matched: only used for utf8 flag; the string
        itself is accessed via the pointers below. Note that on
        something like an overloaded SV, SvPOK(sv) may be false
        and the string pointers may point to something unrelated to
        the SV itself.
strbeg: real beginning of string
strpos: the point in the string at which to begin matching
strend: pointer to the byte following the last char of the string
flags   currently unused; set to 0
data:   currently unused; set to NULL

checkstr

SV* checkstr(pTHX_ REGEXP * const rx);

Возвращает SV, содержащий строку, которая должна появиться в шаблоне. Используется split для оптимизации сопоставлений.

free

void free(pTHX_ REGEXP * const rx);

Вызывается Perl при освобождении шаблона регулярного выражения, чтобы движок мог освободить любые ресурсы, на которые указывает член pprivate структуры regexp. Это отвечает только за освобождение частных данных; Perl позаботится об освобождении всего остального, содержащегося в структуре regexp.

Числовые вызовы обратного вызова захвата

Вызывается для получения/установления значения $`, $', $& и их именованных эквивалентов, ${^PREMATCH}, ${^POSTMATCH} и ${^MATCH}, а также числовых групп захвата ($1, $2, ...).

Параметр paren будет 1 для $1, 2 для $2 и так далее, и иметь эти символические значения для специальных переменных:

${^PREMATCH}  RX_BUFF_IDX_CARET_PREMATCH
${^POSTMATCH} RX_BUFF_IDX_CARET_POSTMATCH
${^MATCH}     RX_BUFF_IDX_CARET_FULLMATCH
$`            RX_BUFF_IDX_PREMATCH
$'            RX_BUFF_IDX_POSTMATCH
$&            RX_BUFF_IDX_FULLMATCH

Обратите внимание, что в Perl 5.17.3 и более ранних версиях последние три константы также использовались для вариантов переменных с символом ^.

Имена выбраны по аналогии с именами методов Tie::Scalar с дополнительным обратным вызовом LENGTH для повышения эффективности. Однако именованные переменные захвата в настоящее время не привязаны внутренне, но реализованы с помощью магии.

numbered_buff_FETCH

void numbered_buff_FETCH(pTHX_ REGEXP * const rx, const I32 paren,
                         SV * const sv);

Получение указанной по номеру группы захвата. sv должно быть установлено в скаляр для возврата, скаляр передаётся в качестве аргумента, а не возвращается из функции, потому что при вызове Perl уже имеет скаляр для хранения значения, создание другого было бы избыточным. Скаляр можно установить с помощью sv_setsv, sv_setpvn и т. п., см. perlapi.

В этом обратном вызове Perl снимает метки taint со своих собственных переменных захвата в режиме taint (см. perlsec). Обратитесь к функции Perl_reg_numbered_buff_fetch в regcomp.c, чтобы узнать, как снять метку taint с переменных захвата, если вы хотите, чтобы ваш движок тоже это делал.

numbered_buff_STORE

void    (*numbered_buff_STORE) (pTHX_
                                REGEXP * const rx,
                                const I32 paren,
                                SV const * const value);

Устанавливает значение числовой переменной захвата. value — скаляр, который будет использоваться в качестве нового значения. Движок должен убедиться, что он используется в качестве нового значения (или отклонить его).

Пример:

if ("ook" =~ /(o*)/) {
    # 'paren' will be '1' and 'value' will be 'ee'
    $1 =~ tr/o/e/;
}

Свой движок Perl выдаст ошибку при любой попытке изменить переменные захвата. Для этого в другом движке используйте следующий обратный вызов (скопирован из Perl_reg_numbered_buff_store):

void
Example_reg_numbered_buff_store(pTHX_
                                REGEXP * const rx,
                                const I32 paren,
                                SV const * const value)
{
    PERL_UNUSED_ARG(rx);
    PERL_UNUSED_ARG(paren);
    PERL_UNUSED_ARG(value);

    if (!PL_localizing)
        Perl_croak(aTHX_ PL_no_modify);
}

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

package CaptureVar;
use parent 'Tie::Scalar';

sub TIESCALAR { bless [] }
sub FETCH { undef }
sub STORE { die "This doesn't get called" }

package main;

tie my $sv => "CaptureVar";
$sv =~ y/a/b/;

Так как $sv является undef при применении оператора y///, транслитерация фактически не будет выполнена, и программа не die. Это отличается от того, как работали версии 5.8 и более ранние, так как переменные захвата тогда были переменными READONLY; теперь они просто умрут при присваивании в стандартном движке.

numbered_buff_LENGTH

I32 numbered_buff_LENGTH (pTHX_
                          REGEXP * const rx,
                          const SV * const sv,
                          const I32 paren);

Получение length переменной захвата. Для этого есть специальный обратный вызов, чтобы Perl не выполнял FETCH и не применял length к результату, так как длина (в случае Perl) известна из смещения, хранящегося в rx->offs, что намного эффективнее:

I32 s1  = rx->offs[paren].start;
I32 s2  = rx->offs[paren].end;
I32 len = t1 - s1;

В случае UTF-8 это немного сложнее, см., что делает Perl_reg_numbered_buff_length с is_utf8_string_loclen.

Именованные вызовы обратного вызова захвата

Вызывается для получения/установления значения %+ и %-, а также некоторыми служебными функциями в re.

Существует два обратных вызова; named_buff вызывается во всех случаях, когда вызовы обратного вызова FETCH, STORE, DELETE, CLEAR, EXISTS и SCALAR Tie::Hash выполнялись бы при изменениях в %+ и %- и named_buff_iter в тех же случаях, что и FIRSTKEY и NEXTKEY.

Параметр flags может использоваться для определения, на какие операции должны реагировать обратные вызовы. В настоящее время определены следующие флаги:

Какая операция Tie::Hash выполняется на уровне Perl для %+ или %+, если таковая имеется:

RXapif_FETCH
RXapif_STORE
RXapif_DELETE
RXapif_CLEAR
RXapif_EXISTS
RXapif_SCALAR
RXapif_FIRSTKEY
RXapif_NEXTKEY

Если %+ или %- обрабатываются, если таковые имеются.

RXapif_ONE /* %+ */
RXapif_ALL /* %- */

Если это вызывается как re::regname, re::regnames или re::regnames_count, если таковые имеются. Первые два будут объединены с RXapif_ONE или RXapif_ALL.

RXapif_REGNAME
RXapif_REGNAMES
RXapif_REGNAMES_COUNT

Внутренне %+ и %- реализуются с помощью реального интерфейса привязки через Tie::Hash::NamedCapture. Методы в этом пакете будут вызывать эти функции обратного вызова. Однако использование Tie::Hash::NamedCapture для этой цели может измениться в будущих выпусках. Например, это может быть реализовано с помощью магии (требуется расширение mgvtbl).

named_buff

SV*     (*named_buff) (pTHX_ REGEXP * const rx, SV * const key,
                       SV * const value, U32 flags);

named_buff_iter

SV*     (*named_buff_iter) (pTHX_
                            REGEXP * const rx,
                            const SV * const lastkey,
                            const U32 flags);

qr_package

SV* qr_package(pTHX_ REGEXP * const rx);

Пакет, в который благословляется магический объект qr// (как видно в ref qr//). Рекомендуется, чтобы движки меняли это на имя своего пакета для идентификации, независимо от того, реализуют ли они методы на объекте.

Пакет, возвращаемый этим методом, также должен иметь внутренний пакет Regexp в своём @ISA. qr//->isa("Regexp") должно всегда быть истинным, независимо от используемого движка.

Пример реализации может быть:

SV*
Example_qr_package(pTHX_ REGEXP * const rx)
{
    PERL_UNUSED_ARG(rx);
    return newSVpvs("re::engine::Example");
}

Любые вызовы методов на объекте, созданном с помощью qr// , будут перенаправлены в пакет как обычный объект.

use re::engine::Example;
my $re = qr//;
$re->meth; # dispatched to re::engine::Example::meth()

Чтобы получить объект REGEXP из скаляра в функции XS, используйте макрос SvRX, см. "REGEXP Functions" в perlapi.

void meth(SV * rv)
PPCODE:
    REGEXP * re = SvRX(sv);

dupe

void* dupe(pTHX_ REGEXP * const rx, CLONE_PARAMS *param);

В многопоточных сборках регулярное выражение может потребоваться дублировать, чтобы шаблон мог использоваться несколькими потоками. Ожидается, что эта процедура будет обрабатывать дублирование любых частных данных, на которые указывает член pprivate структуры regexp. Она будет вызвана с предварительно созданной новой структурой regexp в качестве аргумента, член pprivate будет указывать на старую частную структуру, и именно эта процедура отвечает за создание копии и возвращение указателя на неё (Perl затем использует его для перезаписи поля, переданного этой процедуре).

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

В однопоточных сборках это поле не существует.

op_comp

Это закрытая функция ядра Perl и может быть изменена. Должна быть равна нулю.

Структура REGEXP

Структура REGEXP определена в regexp.h. Все движки регулярных выражений должны быть способны правильно создать такую структуру в своей процедуре "comp".

Структура REGEXP содержит все данные, которые Perl нужны для корректной работы с регулярным выражением. Она включает данные об оптимизациях, которые Perl может использовать для определения, действительно ли необходимо использовать движок регулярных выражений, и различные другие управляющие сведения, необходимые для корректного выполнения шаблонов в различных контекстах, таких как привязка шаблона к определённому началу, какие флаги использовались во время компиляции или содержит ли программа специальные конструкции, о которых Perl должен знать.

Кроме того, она содержит два поля, предназначенные для частного использования движка регулярных выражений, который скомпилировал шаблон. Это члены intflags и pprivate. pprivate — указатель на произвольную структуру, использование и управление которой являются обязанностью компилирующего движка. Perl никогда не будет изменять ни одно из этих значений.

typedef struct regexp {
    /* what engine created this regexp? */
    const struct regexp_engine* engine;

    /* what re is this a lightweight copy of? */
    struct regexp* mother_re;

    /* Information about the match that the Perl core uses to manage
     * things */
    U32 extflags;   /* Flags used both externally and internally */
    I32 minlen;     /* mininum possible number of chars in */
                       string to match */
    I32 minlenret;  /* mininum possible number of chars in $& */
    U32 gofs;       /* chars left of pos that we search from */

    /* substring data about strings that must appear
       in the final match, used for optimisations */
    struct reg_substr_data *substrs;

    U32 nparens;  /* number of capture groups */

    /* private engine specific data */
    U32 intflags;   /* Engine Specific Internal flags */
    void *pprivate; /* Data private to the regex engine which 
                       created this object. */

    /* Data about the last/current match. These are modified during
     * matching*/
    U32 lastparen;            /* highest close paren matched ($+) */
    U32 lastcloseparen;       /* last close paren matched ($^N) */
    regexp_paren_pair *offs;  /* Array of offsets for (@-) and
                                 (@+) */

    char *subbeg;  /* saved or original string so \digit works
                      forever. */
    SV_SAVED_COPY  /* If non-NULL, SV which is COW from original */
    I32 sublen;    /* Length of string pointed by subbeg */
    I32 suboffset;  /* byte offset of subbeg from logical start of
                       str */
    I32 subcoffset; /* suboffset equiv, but in chars (for @-/@+) */

    /* Information about the match that isn't often used */
    I32 prelen;           /* length of precomp */
    const char *precomp;  /* pre-compilation regular expression */

    char *wrapped;  /* wrapped version of the pattern */
    I32 wraplen;    /* length of wrapped */

    I32 seen_evals;   /* number of eval groups in the pattern - for
                         security checks */
    HV *paren_names;  /* Optional hash of paren names */

    /* Refcount of this regexp */
    I32 refcnt;             /* Refcount of this regexp */
} regexp;

Поля обсуждаются более подробно ниже:

engine

Это поле указывает на структуру regexp_engine, содержащую указатели на подпрограммы, которые необходимо использовать для выполнения сопоставления. Компилирующая процедура отвечает за заполнение этого поля перед возвращением объекта regexp.

Внутренне это устанавливается в NULL, если не указан пользовательский движок в $^H{regcomp}, собственные обратные вызовы Perl можно получить в структуре, на которую указывает RE_ENGINE_PTR.

mother_re

TODO, см. http://www.mail-archive.com/perl5-changes@perl.org/msg17328.html

extflags

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

minlen minlenret

Минимальная длина строки (в символах), необходимая для соответствия шаблону. Это используется для сокращения области поиска, не рассматривая соответствия ближе к концу строки, чем это необходимо для сопоставления. Например, нет смысла даже запускать движок регулярных выражений, если minlen равен 10, а длина строки всего 5 символов. В этом случае шаблон не может соответствовать.

minlenret — минимальная длина (в символах) строки, которая будет найдена в $& после сопоставления.

Разница между minlen и minlenret видна в следующем шаблоне:

/ns(?=\d)/

где minlen будет 3, но minlenret будет только 2, так как \d требуется для сопоставления, но фактически не включена в сопоставленный контент. Это различие особенно важно, так как логика подстановки использует minlenret для определения возможности выполнения подстановок на месте (что может значительно ускорить процесс).

gofs

Левый смещение от pos() для начала сопоставления.

substrs

Данные о подстроках, которые должны присутствовать в окончательном соответствии. В настоящее время это используется только внутренним движком Perl, но в будущем может использоваться всеми движками для оптимизации.

nparens, lastparen, и lastcloseparen

Эти поля используются для отслеживания: количества группирующих захватов в шаблоне; наивысшего захваченного элемента, который был закрыт (см. "$+" в perlvar); и последнего закрытого захваченного элемента (см. "$^N" в perlvar).

intflags

Внутренняя копия флагов, с которыми был скомпилирован шаблон. Обычно это совпадает с extflags, если движок не изменил какой-либо из них.

pprivate

Указатель void* на структуру данных, определённую движком. Движок Perl использует структуру regexp_internal (см. "Базовые структуры" в perlreguts), но пользовательский движок должен использовать что-то другое.

offs

Структура regexp_paren_pair, которая определяет смещения в строке, с которой производится сопоставление, соответствующие $& и $1, $2 и т. д. захватам. Структура regexp_paren_pair определена следующим образом:

typedef struct regexp_paren_pair {
    I32 start;
    I32 end;
} regexp_paren_pair;

Если ->offs[num].start или ->offs[num].end равны -1, то соответствующая группа захватов не соответствовала. ->offs[0].start/end представляет $& (или ${^MATCH} в /p) и ->offs[paren].end соответствует $$paren, где $paren = 1>.

precomp prelen

Используется для оптимизации. precomp содержит копию скомпилированного шаблона, а prelen — его длину. При компиляции нового шаблона (например, внутри цикла) внутренний оператор regcomp проверяет, совпадают ли последний скомпилированный шаблон REGEXP и его precomp и prelen с новым, и если да, то использует старый шаблон вместо компиляции нового.

Соответствующий фрагмент из Perl_pp_regcomp:

if (!re || !re->precomp || re->prelen != (I32)len ||
    memNE(re->precomp, t, len))
/* Compile a new pattern */

paren_names

Это хеш-таблица, используемая внутри для отслеживания именованных групп захватов и их смещений. Ключами являются имена буферов, значениями — dualvars, где слот IV содержит количество буферов с заданным именем, а pv — вложенный массив I32. Значения также могут быть содержаться независимо в массиве данных в случаях использования именованных обратных ссылок.

substrs

Содержит информацию о самой длинной строке, которая должна появляться с фиксированным смещением от начала шаблона, и самой длинной строке, которая должна появляться с плавающим смещением от начала шаблона. Используется для поиска с помощью алгоритма Fast-Boyer-Moore, чтобы определить, стоит ли использовать движок регулярных выражений вообще, и если да, то где в строке начать поиск.

subbeg sublen saved_copy suboffset subcoffset

Используется на этапе выполнения для управления шаблонами поиска и замены и для предоставления текста для $&, $1 и т. д. subbeg указывает на буфер (исходную строку или копию в случае RX_MATCH_COPIED(rx)) и sublen — длина буфера. Начальные и конечные индексы RX_OFFS индексируют этот буфер.

При наличии флага REXEC_COPY_STR, но с добавлением флагов REXEC_COPY_SKIP_PRE или REXEC_COPY_SKIP_POST, движок может выбрать не копировать весь буфер (хотя он должен это делать в присутствии RXf_PMf_KEEPCOPY или соответствующих битов, установленных в PL_sawampersand). В этом случае он может установить suboffset для указания количества байтов от логического начала буфера до физического начала (т. е. subbeg). Он также должен установить subcoffset, количество символов в смещении. Последнее необходимо для поддержки @- и @+, которые работают с символами, а не байтами.

wrapped wraplen

Содержит строку, в которую преобразуется qr// строка. Например, движок Perl хранит (?^:eek) в случае qr/eek/.

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

my $x = qr/a|b/;  # "a|b"
my $y = qr/c/i;   # "c"
my $z = qr/$x$y/; # "a|bc"

Для решения этой проблемы нет другого способа, кроме как заставить пользовательский движок понимать конструкцию, подобную (?:).

seen_evals

Хранит количество групп eval в шаблоне. Это используется в целях безопасности при встраивании скомпилированных регулярных выражений в более крупные шаблоны с qr//.

refcnt

Количество раз, когда структура была проинициализирована. Когда это значение падает до 0, регулярное выражение автоматически освобождается функцией pregfree. Это значение должно быть установлено в 1 в процедуре "comp" каждого движка.

HISTORY

Изначально часть perlreguts.

AUTHORS

Изначально написан Yves Orton, дополнен Ævar Arnfjörð Bjarmason.

LICENSE

Copyright 2006 Yves Orton и 2007 Ævar Arnfjörð Bjarmason.

Эта программа является свободной программой; вы можете перераспределять и/или изменять ее в соответствии с теми же условиями, что и Perl.

© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.32.0/perlreapi

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API