Spec-Zone.ru › Perl 5.38

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) (...);

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

Для установки нового обработчика регулярных выражений $^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.

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 (см. 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 — указатель типа void на произвольную структуру, использование и управление которой возлагается на движок компиляции. 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

Это хеш, используемый для отслеживания именованных групп захвата и их смещений во внутренней работе. Ключи — имена буферов, значения — переменные 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–2023 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.38.0/perlreapi

Spec-Zone.ru

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