Pregunta

Tome el siguiente 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);

Necesito obtener la posición de NAME, FUNC y cada P dentro del objetivo $ (por lo tanto, PREG_OFFSET_CAPTURE). El patrón funciona para Ps, pero no coincide con ninguno de los grupos nombrados & Quot; ruleName & Quot; o " funcName " ;.

¿Qué me estoy perdiendo?

Gracias.

¿Fue útil?

Solución

Creo que he encontrado la razón.

  1. Sus referencias posteriores son opcionales.
  2. Si coinciden (y en el primer intento lo hacen), entonces el motor de expresiones regulares se encuentra a la izquierda de " LPAREN " ;.
  3. La siguiente ficha que el motor de expresiones regulares intenta hacer coincidir es un carácter de espacio. Esto se debe a que la expresión de retrospectiva (?<=LPAREN) no consume caracteres en la cadena.
  4. No puede coincidir con el espacio porque hay una L
  5. El motor regex descarta las coincidencias opcionales de 2. y continúa hasta que encuentra el siguiente espacio.
  6. Coincide y sigue coincidiendo desde entonces, capturando todos los P s. Pero los grupos nombrados tuvieron que ser abandonados para que esto funcione.

No estoy seguro de por qué necesitas mirar atrás. ¿Qué tal

/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top