raggruppamento di fronte a lookbehind positivo non corrispondente
Domanda
Prendi il seguente codice:
$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);
Devo ottenere la posizione di NAME, FUNC e ogni P all'interno del target $ (quindi PREG_OFFSET_CAPTURE). Il modello funziona per Ps, ma non corrisponde a nessuno dei gruppi denominati & Quot; ruleName & Quot; oppure " funcName " ;.
Cosa mi sto perdendo?
Grazie.
Soluzione
Penso di aver trovato il motivo.
- I tuoi riferimenti indietro sono facoltativi.
- Se corrispondono (e al primo tentativo lo fanno), allora il motore regex è in piedi a sinistra di " LPAREN " ;.
- Il token successivo che il motore regex cerca di abbinare è un carattere spazio. Questo perché l'espressione lookbehind
(?<=LPAREN)
non consuma caratteri nella stringa. - Non può corrispondere allo spazio perché c'è una L
- Il motore regex scarta le corrispondenze opzionali da 2. e continua fino a quando non trova lo spazio successivo.
- Si abbina e continua a corrispondere da quel momento in poi, catturando tutti i
P
s. Ma i gruppi nominati dovevano essere abbandonati perché questo funzionasse.
Non sono sicuro del motivo per cui hai bisogno di guardare dietro. Che ne dici di
/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow