用()分組
使用原子組
原子組的格式為 (?>...)
,並且在開啟的 paren 之後具有 ?>
。
請考慮以下示例文字:
ABC
正規表示式將嘗試匹配從文字的位置 0 開始,即在 ABC
中的 A
之前。
如果使用不區分大小寫的表示式 (?>a*)abc
,(?>a*)
將匹配 1 A
字元,離開
BC
作為匹配的剩餘文字。退出 (?>a*)
組,並嘗試對剩餘的文字進行 abc
,該文字無法匹配。
引擎無法回溯到原子組,因此當前傳遞失敗。引擎移動到文字中的下一個位置,該位置位於 A
之後和 B
之前的位置 1。
再次嘗試 regex (?>a*)abc
,(?>a*)
匹配 A
0 次,離開
BC
作為匹配的剩餘文字。(?>a*)
組退出並嘗試 abc
,但失敗了。
同樣,引擎無法回溯到原子組,因此當前傳遞失敗。正規表示式將繼續失敗,直到文字中的所有位置都已用完為止。
使用非原子組
常規非捕獲組的格式為 (?:...)
,並且在開啟的 paren 之後具有 ?:
。
給定相同的示例文字,但使用不區分大小寫的表示式 (?:a*)abc
,將發生匹配,因為允許發生回溯。
首先,(?:a*)
將在文字中使用字母 A
ABC
離開
BC
作為匹配的剩餘文字。退出 (?:a*)
組,並嘗試對剩餘的文字進行 abc
,該文字無法匹配。
引擎回溯到 (?:a*)
組並嘗試匹配少 1 個字元:它不是匹配 1 個 A
字元,而是嘗試匹配 0 A
個字元,並退出 (?:a*)
組。這離開了
ABC
作為匹配的剩餘文字。正規表示式現在能夠成功匹配剩餘的文字。
其他示例文字
考慮這個示例文字,包括原子和非原子組(同樣,不區分大小寫):
AAAABC
正規表示式將嘗試匹配從文字的位置 0 開始,即在 AAAABC
中的第一個 A
之前。
使用原子組 (?>a*)abc
的模式將無法匹配,表現幾乎與上面的原子 ABC
示例相同:所有 4 個 A
字元首先與 (?>a*)
匹配(留下 BC
作為剩餘文字以匹配),並且 abc
無法匹配該文字。該組無法重新輸入,因此匹配失敗。
使用非原子組 (?:a*)abc
的模式將能夠匹配,表現類似於上面的非原子 ABC
示例:所有 4 個 A
字元首先與 (?:a*)
匹配(留下 BC
作為匹配的剩餘文字),並且 abc
無法匹配該文字。基團是能夠重新輸入,所以少了一個 A
嘗試:3 個 A
字元匹配代替 4-(留下 ABC
作為剩餘的文字相匹配),並且 abc
能夠成功地匹配該文字。