agrupamento em frente lookbehind positivo não corresponde
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.
Solução
Eu acho que eu encontrei a razão.
- Seus backreferences nomeados são opcionais.
- Se forem iguais (e na primeira tentativa eles fazem), então o motor regex está de pé para a esquerda de "LPAREN".
- 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. - Não pode coincidir com o espaço, porque há um L
- As devoluções motor regex os jogos opcionais de 2. e continua até encontrar o próximo espaço.
- Combina e mantém correspondência a partir de então, capturando todos os
P
s. 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