2016-06-18 82 views
0

我試圖匹配的字符串做不是擬合模式name (CA)barbaz (UK)。我似乎已經解決了使用應答here的問題,但是這是我開始的,我不知道爲什麼它不工作:否定預測混淆

var r1 = /^.+(?!\([A-Z]{2}\))$/; 

r1.test('foo'); //true 

r1.test('foo (US)'); //whoops -also true 

從閱讀否定前瞻doc我希望任何例如,沒有跟隨的字符串(JP)將導致匹配,而任何後跟例如, (DE)會失敗。 (只有前者​​正在被滿足)。

我想也許.+是一種「消費」的一切,抵消先行,所以我嘗試

r2 = /^[^()]+(?!\([A-Z]+\))$/; 

r2.test('name (US)'); //false 

r2.test('foo('); //whoops -also false 

不過,我需要的東西像foo(相匹配。

爲什麼我第一次嘗試失敗?

回答

1

在您的第一個表達式中,.+消耗整個字符串,然後先行測試 - 它不匹配,因爲沒有剩餘字符。要達到目標,您可以使用/^(?!.+\([A-Z]{2}\)$).+$/ - 首先檢查不需要的構造不存在,然後進行匹配。

請參閱https://regex101.com/r/aG7xZ0/1與您的樣品

+0

感謝您的鏈接。你能詳細說明你如何使用$? – KnewB

+1

它只是用來確保'(XX)'只匹配字符串的末尾,而不是中間的某個地方,所以'Hello(XX)World'將是有效的。 –

+0

很酷我認爲它涵蓋了前瞻中的一個,但最後有'。+ $'? – KnewB