Eclesiastes

Ícone

Sobre o que é este blog? O.o

Callouts

NOTA: O texto abaixo é uma tradução minha da PCRE Man Pages – PCRECALLOUT(3).

int (*pcre_callout)(pcre_callout_block *);

PCRE fornece o que é chamado de “callout”, que é um meio de temporariamente passar o controle ao invocador da PCRE no meio da combinação de um padrão. O invocador do PCRE provê uma função externa para colocar pontos de entrada na variável global pcre_callout. Por padrão, esta variável contém NULL, que desabilita toda chamada externa.

 Na expressão regular, (?C) indica o ponto em que a função externa é chamada. Diferentes pontos de callout podem ser identificados colocando um número menor que 256 depois da letra C. O valor padrão é zero. Por exemplo, este padrão contém 2 pontos de callout:

(?C1)eabc(?C2)def

Se a opção PCRE_AUTO_CALLOUT é definida quando pcre_compile() é chamada, PCRE automaticamente insere callouts, todos com número 255, antes de cada item do padrão. Por exemplo, se PCRE_AUTO_CALLOUT é usado com o padrão

A(\d{2}|--)

Ele é processado com se ele fosse

(?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)

Note que há callout antes e depois de cada parêntese e barra de alternação. Callouts automáticos podem ser usado para rastrear o progresso de combinação de um padrão. O comando pcretest tem uma opção para definir callouts automáticos; quando isto é usado, a saída indica como o padrão é combinado. Uma informação útil quando você está tentando otimizar a performance de um padrão em particular.

Faltando Callouts

Você pode ficar ciente que, por causa das otimizações na forma que a PCRE combina padrões, callouts as vezes podem não ocorrer. Por exemplo, se o padrão é

ab(?C4)cd

PCRE sabe que para alguma string combinar precisa conter a letra “d”. Se a string é “abyz”, a falta de “d” faz com que a combinação não comece, e o callout não é alcançado. Contudo, com “abyd”, embora o resultado ainda não combine, o callout é obedecido.

A interface Callout

Durante a combinação, quando PCRE alcança um ponto de callout, a função externa definida por pcre_callout é chamada (se ela é definida). Isto se aplica para ambas as funções pcre_exec() e pcre_dfa_exec(). O único argumento da função callout é um ponteiro para um bloco pcre_callout. Esta estrutura contém os seguinte campos:

int version;
int callout_number;
int *offset_vector;
const char *subject;
int subject_length;
int start_match;
int current_position;
int capture_top;
int capture_last;
void *callout_data;
int pattern_position;
int next_item_length;

O campo version é um inteiro contendo o número da versão do formato do bloco. A versão inicial é 0; a atual é 1. O número da versão será modificado no futuro se campos forem adicionados, mas a intenção é nunca remover um campo já existente.

O campo callout_number contém o número do callout, como compilado para o padrão (isto é, o número depois do ?C definidos manualmente, e 255 para para callouts gerados automaticamente).

O campo offset_vector é um ponteiro para o vetor de offsets que serão passados pelo invocador para pcre_exec() ou pcre_dfa_exec(). Quando pcre_exec() é usado, o conteúdo pode ser analisado na ordem para extrair substrings que serão combinadas mais tarde, da mesma forma extraindo substrings depois de uma combinação completada. Para pcre_dfa_exec() este campo não é muito útil.

Os campos subject e subject_length contêm cópias dos valores que são passados para pcre_exec().

O campo start_match contêm o offset na string em que a combinação atual é iniciada. Se o padrão não é ancorado, a função callout pode ser chamada várias vezes para o mesmo ponto no padrão para diferentes pontos de início na string.

O campo current_position contêm o offset do ponto atual da string analisada.

Quando a função pcre_exec() é usada, o campo capture_top contêm um número maior que o mais alto número da substring capturada. Se não há substrings capturadas, o valor de capture_top é 1. Este é sempre o caso quando pcre_dfa_exec() é usada, porque ela não suporta capturar substrings.

O campo capture_last contêm o número da mais recente substring capturada. Se não há substrings capturadas, o valor é -1. Este é sempre o caso quando pcre_dfa_exec() é usada.

O campo capture_data contém o valor que é passado para pcre_exec() ou pcre_dfa_exec() especificamente de modo que possa ser repassado nas callouts. É passado no campo pcre_callout da estrutura pcre_extra. Se nada é passado, o valor de callout_data no bloco pcre_callout é NULL. Há uma descrição da estrutura pcre_extra na documentação pcreapi.

O campo pattern_position é presente na versão 1 da estrutura pcre_callout. Ele contêm o offset para o próximo item a ser combinado no padrão.

O campo next_item_length é presente na versão 1 da estrutura pcre_callout. Ele contém o tamanho do próximo item a ser combinado no padrão. Quando o callout imediatamente precede uma barra de alternação, um feche parêntese, ou o final do padrão, o tamanho é zero. Quando o callout precede um abre parênteses, o tamanho é o subpadrão inteiro.

Os campos pattern_position e next_item_length são pretendidos para ajudar na distinção entre diferentes callouts automaticos, que todos tem o mesmo número de callout. Contudo, eles são definidos para todos callouts.

Retornando valores

A função externa callout retorna um inteiro para PCRE. Se o valor é zero, a combinação procede como normal. Se o valor é maior que zero, a combinação falhou no ponto atual, mas o teste de outra combinação possível segue à frente, exatamente como se um lookahead assertion tivesse falhado. Se o valor é menor que zero, a combinação é abandonada, e pcre_exec() (ou pcre_dfa_exec()) retorna um valor negativo.

Valor negativo são normalmente para se escolher o conjunto de valores PCRE_ERROR_xxx. Em particular, PCRE_ERROR_NOMATCH força um padrão de falha “no match”. O número do erro PCRE_ERROR_CALLOUT é reservado para usar pelas funções callout; ele nunca é usado pela PCRE.

Referência

Publiquei um exemplo aqui!

Arquivado em:C/C++, PCRE

2 Responses

  1. […] Visualizando combinação com pcretest Publicado Maio 9th, 2007 PCRE , Regex Para acompanhar o processo de combinação de uma expressão regular com a lib. PCRE, você pode usar o modificador C na expressão regular informada no programa pcretest. Desta forma, será habilitado o PCRE_AUTO_CALLOUT. Informações sobre Callout podem ser vistas aqui. […]

  2. Cooler disse:

    show bom psot podia ter mais exemplos do uso do pcre
    este link ta quebrado http://ecl.zoone.com.br/pcre_callout.txt

    entre ai depois tambem ando postando artigos de C

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: