在介紹完正則表達式的元字符、重復、分組的概念后,基本上我們對正則表達式的基本使用就OK了,本文我們講一下正則表達式的高階使用方式。
本節我們講一下幾種正則表達式的高級使用方式:
1. 正則表達式的后向引用 。
2. 零寬斷言的概念及使用場景。
3. 負向零寬斷言的概念及使用場景。
4. 冗長的平衡組合遞歸匹配。
一、后向引用
這里我們先舉個例子,當我們需要匹配類似“taobao taobao”,“jingdong jingdong”這樣的內容時,我們的正則表達式怎么寫呢?
答: 可以使用 \b(\w+)\b\s+(\1) 來進行匹配。
下面解釋一下具體的含義:這里 \b(\w+)\b 表示匹配的內容為字符串,(\1) 表示后向引用第1分組的內容進行匹配,所以,最終我們就能匹配到上面我們提到的場景的內容。

二、零寬斷言
為什么會有零寬斷言呢?是為了解決什么問題呢? 這個零寬斷言的存在是為了解決我們一些特點的匹配要求,且不需要占位數。
零寬斷言有正向、負向、先行、后行,一共有4種組合形式:
- (?=exp) 零寬正向先行斷言: 匹配exp前面的位置
- (?<=exp) 零寬正向后行斷言:匹配exp后面的位置
- (?!exp) 零寬負向先行斷言: 匹配后面跟的不是exp的位置
- (?<!exp) 零寬負向后行斷言:匹配前面不是exp的位置
下面可以結合一個例子對零寬斷言進行理解:

三、平衡組遞歸匹配
這里我們先提出一個匹配特定內容的問題:如何把 xx <aa <bbb> <bbb> aa> yy 這樣的字符里,最長的配對的尖括號內的內容捕獲出來?
這里我們可以使用平衡組遞歸進行匹配,思路如下:
1. 我們可以使用 (?'group') 把捕獲的內容命名為group,並壓入堆棧(Stack)
2. 通過 (?'-group')從堆棧上彈出最后壓入堆棧的名為group的捕獲內容,如果堆棧本來為空,則本分組的匹配失敗。
3. 通過(?(group)yes|no)來判斷,如果堆棧上存在以名為group的捕獲內容的話,繼續匹配yes部分的表達式,否則繼續匹配no部分。
需要注意的是:目前僅僅 .Net 支持平衡組遞歸匹配,其他語言例如Java、JavaScript 目前都不支持。這里我也就不過多的展開討論和說明了。
