Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

optional regex lookahead

I'm trying to get an optional lookahead but am having problems where as soon as I make it optional (add a ? after it), it no longer matches even when the data is there.

As a brief summary, I'm trying to pull specific querystring params out of a URI. Example:

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

I'll break that out a bit:

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

The above example works perfectly under the condition that both foo and bar exist as parameters in the querystring. The issue is that I'm trying to make these optional, so I changed it to:

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

and it no longer matches any parameters, though it still matches foo.html. Any ideas?

like image 884
Nobody Avatar asked Jan 26 '12 01:01

Nobody


People also ask

What is a Lookbehind regex?

Regex Lookbehind is used as an assertion in Python regular expressions(re) to determine success or failure whether the pattern is behind i.e to the right of the parser's current position. They don't match anything. Hence, Regex Lookbehind and lookahead are termed as a zero-width assertion.

Can I use regex lookahead?

Lookahead assertions are part of JavaScript's original regular expression support and are thus supported in all browsers.

What is positive and negative lookahead?

Positive lookahead: (?= «pattern») matches if pattern matches what comes after the current location in the input string. Negative lookahead: (?! «pattern») matches if pattern does not match what comes after the current location in the input string.


1 Answers

Try to put the question marks into the look-ahead:

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

Looks odd, but I think a good-looking regex wasn't the aim :-)

Also, have you thought about this one?

/.*foo.html\??.*(?:foo|bar)=([^\&]+).*(?:bar|foo)=([^\&]+)/
like image 85
Bergi Avatar answered Oct 07 '22 04:10

Bergi