2016-10-06 68 views
2

我想知道事情如何與積極lookahead實際工作。雖然這樣做,但我已經達到了我想要捕獲ABC和PQR之間任何東西的地步,其中ABC包括ABC和PQR之間的'mao'。使用積極Lookahead時不一致

事情似乎與合作:

ABC(?=.*?mao).*?PQR 

下它被罰款,除了在一種情況下,看我的截圖爲:

enter image description here

我認爲紅色標記的塊,不應該沒有匹配。

I have tried it here

有人能請解釋一下我在這裏做錯了,爲什麼匹配?

回答

1

(?=.*?mao)後可PQR因爲.匹配任何字符(如果DOTALL模式未開啓,所有除換行符符號)找到mao。在zxcABCdddddddPQRaasd which contains mao inside中,mao出現在與PQR相同的行上的換行符以外的任何0+字符之後,因此該前瞻返回true

爲了避免這種情況,使用tempered greedy token

ABC(?=(?:(?!PQR).)*mao).*?PQR 
     ^^^^^^^^^^^^^ 

this demo(你也可以使用*?,而不是*,這將只是讓懶惰)。

(?=(?:(?!PQR).)*mao)結構將只返回後0+字符真正如果mao出現不啓動PQR字符序列(即,如果PQRmao出現之前)。

+0

請您解釋一下爲什麼「(?=。*?mao)」可以在PQR之後找到mao? –

+0

「在包含mao的zxcABCdddddddPQRaasd中,mao出現在與PQR同一行上的linebreaks符號以外的任何0+字符之後,因此該lookahead返回true。」 ---我已經設置了邊界PQR爲什麼這會超越它,我認爲我在概念上有一些問題 –

+0

是的,'。*?mao'解釋是:'。*?'匹配除換行符之外的任何零個或多個字符符號儘可能少,但儘可能多地返回有效匹配,直到第一個「mao」。 –

1

如果您想「捕獲ABC和PQR之間的任何內容,包括'ABC'和PQR之間的'mao',則不需要在預見中包含.*。只需使用:

ABC.*(?=mao).*PQR 

Test yourself

編輯:噢,我的,這是一個有點早 - 滿足您的要求,因爲在這個問題給出的,它在所有使用前瞻是沒有必要的。這是不夠的:

ABC.*mao.*PQR 

當然這與重新出現啓動(ABC)和結束的問題(PQR)令牌,就像ABCandABCmaoPQRABCmaoPQRmaoPQR,它可能會匹配更多,你想它。 I've updated the regex here to include these sample cases

編輯2:剛纔看到,您的一個測試字符串ABC1234sakasdf mao mao aslkdfPQR dsfgasd mao maoPQR已經涵蓋了我在上面的段落中提到的內容。我需要一杯咖啡。

+0

請注意,ABC。*(?= mao)。* PQR'正則表達式與OP正則表達式不一樣,因爲它匹配最後一個在其之前有'mao'的'PQR'。如果您將其更改爲「ABC。*?mao。*?PQR」,它將更接近,但它也會匹配「ABC 1 PQR mao aslkdf PQR」 - 不確定是否有預期。 –

相關問題