Pergunta

Tome o seguinte código:

$target = 'NAME FUNC LPAREN P COMMA P COMMA P RPAREN';
//$target = 'NAME FUNC LPAREN P RPAREN';
//$target = 'NAME FUNC LPAREN RPAREN';
$pattern = '/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:(?<=LPAREN)(?: (?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA)))/';

preg_match_all($pattern,$target,$matches,PREG_OFFSET_CAPTURE|PREG_PATTERN_ORDER);

Eu preciso para obter a posição do NOME, do FUNC e cada P dentro do $ target (assim PREG_OFFSET_CAPTURE). O padrão funciona para Ps, mas não coincide com qualquer um dos grupos denominados "ruleName" ou "nome_da_função".

O que eu estou ausente?

Graças.

Foi útil?

Solução

Eu acho que eu encontrei a razão.

  1. Seus backreferences nomeados são opcionais.
  2. Se forem iguais (e na primeira tentativa eles fazem), então o motor regex está de pé para a esquerda de "LPAREN".
  3. O próximo token as tentativas motor regex para coincidir é um caractere de espaço. Isso ocorre porque o (?<=LPAREN) expressão lookbehind não consome caracteres na cadeia.
  4. Não pode coincidir com o espaço, porque há um L
  5. As devoluções motor regex os jogos opcionais de 2. e continua até encontrar o próximo espaço.
  6. Combina e mantém correspondência a partir de então, capturando todos os Ps. Mas os grupos nomeados teve de ser abandonado para que isso funcione.

Eu não sei por que você precisa do lookbehind. Como cerca

/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top