2012-01-26 41 views
9

我試圖得到一個可選的lookahead,但有問題,只要我讓它可選(在它後面添加一個?),即使數據存在,它也不再匹配。可選的正則表達式lookahead

作爲一個簡短的總結,我試圖從URI中提取特定查詢字符串參數。例如:

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

我會打破了一點:

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

上面的例子,這兩個foobar存在如在查詢字符串參數的條件下完美。問題是,我試圖使這些可選的,所以我把它改爲:

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

,它不再匹配任何參數,但它仍然匹配foo.html。有任何想法嗎?

+0

你爲什麼使用正則表達式呢?只需拆分字符串並將鍵/值對存儲在對象中即可。 – ThiefMaster

+0

@ThiefMaster - 因爲我想:)而現在我想更多的是它不會工作。實際上,這僅僅是因爲當我只需要獲得2個參數時代碼更短。 –

+0

爲什麼你需要lookahead?要匹配foo.html?bar = baz&foo = true以及? – Bergi

回答

4

嘗試把問號變成前瞻:

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

看起來很奇怪,但我覺得好看的正則表達式是不是:-)

同樣的目的,有你想過這個嗎?

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

謝謝,第一個作品。我認爲這是必需的,因爲引擎可能會完全優化'(?=)?'(即只是忽略它),因爲可選的不匹配正則表達式毫無意義。我只是碰巧用它來抓別的東西。你的第二個也會工作,除了需要做一些調整才能使每個參數可選,並且事實上有更多的邏輯,因爲你需要弄清哪個參數是在哪裏的(你需要刪除兩個''? :'然後檢查這些) –

+0

無論如何,使lookahead可選將導致匹配一個空字符串。 – Bergi