我們不僅可以在結果或替換字串中使用擷取群組 (...)
的內容,還可以在模式本身中使用。
依據數字進行反向引用:\N
可以使用 \N
在模式中參照群組,其中 N
是群組編號。
為了清楚說明為什麼這很有用,我們來考慮一個任務。
我們需要找出帶引號的字串:單引號 '...'
或雙引號 "..."
– 兩種變體都應該符合。
如何找出它們?
我們可以將兩種引號都放在方括號中:['"](.*?)['"]
,但它會找出帶有混合引號的字串,例如 "...'
和 '..."
。當一個引號出現在另一個引號內時,這將導致不正確的比對,例如在字串 "She's the one!"
中
let str = `He said: "She's the one!".`;
let regexp = /['"](.*?)['"]/g;
// The result is not what we'd like to have
alert( str.match(regexp) ); // "She'
如我們所見,模式找到一個開啟引號 "
,然後文字會被消耗到另一個引號 '
,它會關閉匹配。
為了確保模式尋找的關閉引號與開啟引號完全相同,我們可以將它包進一個擷取群組並反向參照它:(['"])(.*?)\1
。
以下是正確的程式碼
let str = `He said: "She's the one!".`;
let regexp = /(['"])(.*?)\1/g;
alert( str.match(regexp) ); // "She's the one!"
現在它運作了!正規表示式引擎會找到第一個引號 (['"])
並記住它的內容。那是第一個擷取群組。
在模式中的 \1
表示「找到與第一個群組中相同的文字」,在我們的例子中就是完全相同的引號。
類似地,\2
表示第二個群組的內容,\3
表示第三個群組,以此類推。
請注意
如果我們在群組中使用 ?:
,那麼我們就無法參照它。從擷取中排除的群組 (?:...)
沒有被引擎記住。
不要搞混:在模式中的
\1
,在替換中的:$1
在替換字串中我們使用美元符號:$1
,而在模式中則使用反斜線 \1
。
按名稱反向參照:\k<name>
如果一個正規表示式有很多括號,那麼給它們命名會很方便。
為了參照一個命名群組,我們可以使用 \k<name>
。
在下面的範例中,帶有引號的群組被命名為 ?<quote>
,所以反向參照是 \k<quote>
let str = `He said: "She's the one!".`;
let regexp = /(?<quote>['"])(.*?)\k<quote>/g;
alert( str.match(regexp) ); // "She's the one!"
留言
<code>
標籤,若要插入多行程式碼,請將它們包在<pre>
標籤中,若要插入超過 10 行的程式碼,請使用沙盒 (plnkr、jsbin、codepen…)