2012-01-26 16 views
9

Sto cercando di ottenere un lookahead opzionale ma sto avendo problemi dove non appena lo renderò opzionale (aggiungi un ? dopo di esso), non corrisponde più nemmeno quando i dati sono lì.opzionale regex lookahead

In breve, sto cercando di estrarre parametri specifici di querystring da un URI. Esempio:

/.*foo.html\??(?=.*foo=([^\&]+))(?=.*bar=([^\&]+))/ 
    .exec('foo.html?foo=true&bar=baz') 

rompo che un bit:

.*foo.html\??  // filename == `foo.html` + '?' 
(?=.*foo=([^\&]+)) // find "foo=...." parameter, store the value 
(?=.*bar=([^\&]+)) // find "bar=...." parameter, store the value 

L'esempio precedente funziona perfettamente a condizione che sia foo e bar esistono come parametri nella querystring. Il problema è che sto cercando di rendere questi opzionale, quindi l'ho cambiato in:

/.*foo.html\??(?=.*foo=([^\&]+))?(?=.*bar=([^\&]+))?/ 
           ↑     ↑ 
    Added these question marks ─┴──────────────────┘ 

e corrispondono a più parametri, anche se corrisponde ancora foo.html. Qualche idea?

+0

Perché stai utilizzando le espressioni regolari per questo? Basta dividere la stringa e memorizzare le coppie chiave/valori in un oggetto. – ThiefMaster

+0

@ThiefMaster - Perché voglio :) E voglio ancora di più ora che non funzionerà. In realtà, è semplicemente perché il codice è molto più breve quando ho solo bisogno di ottenere 2 parametri. –

+0

Perché hai bisogno di guardare avanti? Per abbinare foo.html? Bar = baz & foo = true pure? – Bergi

risposta

4

provare a mettere i punti interrogativi nel look-ahead:

...((?=(?:.*foo=([^\&]+))?)... 

sembra strano, ma penso che un bell'aspetto espressione regolare non era l'obiettivo :-)

Inoltre, averti pensato a questo?

/.*foo.html\??.*(?:foo|bar)=([^\&]+).*(?:bar|foo)=([^\&]+)/ 
+1

Grazie, il primo funziona. Penso che questo sia necessario perché il motore potrebbe ottimizzare '(? =)?' Completamente (cioè ignorandolo) poiché una regex opzionale non corrispondente è, beh, inutile. Mi è capitato di usarlo per catturare qualcos'altro. Il tuo secondo funzionerebbe, eccetto che avrebbe bisogno di qualche ritocco per rendere ogni param opzionale, e c'è un po 'più di logica dopo il fatto dato che hai bisogno di capire quale param è dove (dovresti rimuovere i due '? : ''s quindi controllare contro quelli) –

+0

In ogni caso, rendere il lookahead opzionale porterebbe ad associare una stringa vuota. – Bergi