目前為止,總共介紹了括號的三種用途:
- 分組:將相關(guān)的元素歸攏到一起,構(gòu)成單個元素栗弟;
- 多選結(jié)構(gòu):規(guī)定可能出現(xiàn)的多個子表達式吐葵;
- 引用分組:將子表達式匹配的文本存儲起來规揪,供之后引用
這三種用途并不是彼此獨立的,而是相互重疊的:
- 單純的分組可以視為“只包含一個多選分支的多選結(jié)構(gòu)”温峭;
- 整個多選結(jié)構(gòu)也會被視為單個元素猛铅,可以由一個量詞限定;
- 只要出現(xiàn)了括號凤藏,正則表達式在匹配時就會把括號內(nèi)的子表達式存儲起來提供引用奸忽;
但有時如果不需要引用,保存括號分組的引用信息就會影響性能揖庄;如果表達式比較復(fù)雜栗菜,要處理的文本又很多,更可能嚴重影響性能蹄梢。
為了解決這種問題疙筹,正則表達式提供了非捕獲分組(non-capturing group)。非捕獲分組類似普通捕獲分組,只是在開括號后面緊跟一個問號和冒號(?:...)
而咆,這樣的括號叫做非捕獲型括號霍比,它只能限定量詞的作用范圍,不能捕獲文本暴备。在引用分組時悠瞬,分組的編號同樣會按開括號出現(xiàn)的順序從左向右遞增,只是必須以捕獲分組為準涯捻,非捕獲分組會略過浅妆。
例3-35 非捕獲型分組的使用
# 非捕獲型分組
print(re.search(r'(\d{4})-(\d{2})-(\d{2})', '2018-12-20').group(1)) # 2018
print(re.search(r'(?:\d{4})-(\d{2})-(\d{2})', '2018-12-20').group(1)) # 12
非捕獲型分組不需要保存匹配的文本,整個表達式的效率也因此提高汰瘫,但是看起來不如捕獲分組美觀狂打。不過,如果只需要使用括號的分組或者讀選結(jié)構(gòu)的功能混弥,而沒有用到引用分組趴乡,則應(yīng)當盡量使用非捕獲型括號。