子組通過圓括號分隔界定,并且它們可以嵌套。 將一個模式中的一部分標記為子組(子模式)主要是來做兩件事情:
將可選分支局部化。比如,模式cat(arcat|erpillar|)
匹配 ”cat”, “cataract”,
“caterpillar” 中的一個,如果沒有圓括號的話,它匹配的則是 ”cataract”,
“erpillar” 以及空字符串。
將子組設定為捕獲子組(向上面定義的)。當整個模式匹配后, 目標字符串中匹配子組的部分將會通過 pcre_exec()() 的 ovector 參數(shù)回傳給調(diào)用者。 左括號從左至右出現(xiàn)的次序就是對應子組的下標(從 1 開始), 可以通過這些下標數(shù)字來獲取捕獲子模式匹配結(jié)果。
比如,如果字符串 ”the red king” 使用模式((red|white)
(king|queen))
進行匹配,
模式匹配到的結(jié)果是 array(“red king”, ”red king”, “red”, “king”) 的形式,
其中第 0 個元素是整個模式匹配的結(jié)果,后面的三個元素依次為三個子組匹配的結(jié)果。
它們的下標分別為 1, 2, 3。
事實上,并不一定同時需要圓括號的兩種功能。
經(jīng)常我們會需要子組進行分組, 但又不需要(單獨的)捕獲它們。
在子組定義的左括號后面緊跟字符串 ”?:” 會使得該子組不被單獨捕獲,
并且不會對其后子組序號的計算產(chǎn)生影響。比如, 如果字符串 "the white queen"
匹配模式 the ((?:red|white) (king|queen))
,
匹配到的子串是 "white queen" 和 "queen",
他們的下標分別是 1 和 2。
捕獲子組的最大序號為 65535。然而由于 libpcre 的配置,我們可能無法編譯這么長的
正則表達式。
為了方便簡寫,如果需要在非捕獲子組開始位置設置選項, 選項字母可以位于 ? 和 : 之間,比如兩個模式:
(?i:saturday|sunday) (?:(?i)saturday|sunday)
匹配到了完全相同的字符集。因為可選分支會從左到右嘗試每個分支, 并且選項沒有在子模式結(jié)束前被重置, 并且由于選項的設置會穿透對后面的其他分支產(chǎn)生影響,因此, 上面的模式都會匹配 ”SUNDAY” 以及 ”Saturday”。
可以對子組使用 (?P<name>pattern)
的語法進行命名。
這個子模式將會在匹配結(jié)果中同時以其名稱和順序(數(shù)字下標)出現(xiàn),
還有兩種為子組命名的語法:
(?<name>pattern)
和 (?'name'pattern)
。
有時需要多個匹配可以在一個正則表達式中選用子組。
為了讓多個子組可以共用一個后向引用數(shù)字的問題,
(?|
語法允許復制數(shù)字。
考慮下面的正則表達式匹配Sunday
:
(?:(Sat)ur|(Sun))day
這里當后向引用 1 空時Sun
存儲在后向引用 2 中。
當后向引用 2 不存在的時候 Sat
存儲在后向引用 1中。 使用
(?|
修改模式來修復這個問題:
(?|(Sat)ur|(Sun))day
使用這個模式,
Sun
和 Sat
都會被存儲到后向引用 1 中。