Spec-Zone.ru › Perl 5.36

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 в многопоточной среде для передачи дополнительного аргумента в функцию, содержащую указатель на интерпретатор, выполняющий regexp. В многопоточных средах все функции получают дополнительный аргумент.

Обратные вызовы

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 флагов был скомпилирован regex. Она также содержит дополнительную информацию, например, если 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

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

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 == '^') даже в многопоточной среде; см. 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 снимает флаг загрязнения со своих собственных переменных захвата в режиме загрязнения (см. perlsec). См. функцию Perl_reg_numbered_buff_fetch в regcomp.c, чтобы узнать, как снять флаг загрязнения с переменных захвата, если это то, что вы хотите сделать и в вашем движке.

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 выведет ошибку при любой попытке изменить переменные захвата. Для этого в другом движке используйте следующий обратный вызов (скопирован из %%%CODE_BLOCK_103%%):

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, см. коммит 28d8d7f41a.

extflags

Perl использует это для определения флагов, с которыми было скомпилировано регулярное выражение. Обычно это устанавливается в значение параметра flags в обратном вызове 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

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

substrs

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

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" каждого движка.

ИСТОРИЯ

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

АВТОРЫ

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

ЛИЦЕНЗИЯ

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

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

© 1993–2021 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.36.0/perlreapi

Spec-Zone.ru

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