正則表達式(三)
括號
分組
量詞可以作用字符或者字符組后面作為限定出現次數,如果是限制多個字符出現次數或者限制一個表達式出現次數,需要使用括號()將多個字符或者表達式括起來,這樣便稱為分組。例如(ab)+表示“ab”字符串重復出現一次以上,ab+表示字符b重復出現一次以上。
分組應用:匹配一個長度為15到18的數字字符串,使用正則表達式\d{15,18};匹配一個長度為15或18的數字字符串,使用正則表達式\d{15}(\d{13})?。
多選結構
多選結構的形式是(...|...),在括號內以豎線分隔開多個表達式,每個表達式被稱為多選分支,多選分支的數目是沒有限制的。匹配過程中,整個多選結構看做一個整體,只要其中一個多選分支能夠匹配,則整個多選結構匹配成功。反之,所有多選分支不能匹配則匹配失敗。
繼分組應用中問題來說,匹配一個長度為15或者18的數字字符串,使用正則表達式\d{15}(\d{13})?可以實現,使用多選結構(\d{15}|\d{18})也可以輕松實現。
多選結構應用:匹配月份,使用正則表達式(0?[1-9]|1[012]),匹配日,使用正則表達式(0?[1-9]|1[0-9]|2[0-9]|3[01])。
分組是對字符串特性的抽象合並,多選結構是對字符串特性的具象羅列。
引用分組
分組可以保存每個分組的匹配文本,匹配完成以后,通過group(num)方法引用分組在匹配過程中捕獲的匹配文本。其中num表示對應括號的編號,括號分組的編號自左向右,由1開始計數。一般來說,正則表達式匹配完成以后,會返回一個結果對象,對結果對象調用group()方法,並傳入所需分組的編號,即可獲得所需分組的匹配文本內容。如python而言,re.search()返回一個MatchObject對象,判定MatchObject對象是否為None,可以驗證匹配是否成功;對MatchObject對象調用group()方法可以回去對象中匹配文本的內容。
num = 1,2,3,...MatchObject.group(num)表示獲取對應括號分組編號匹配的內容。
num = 0,MatchObject.group(0)表示獲取整個表達式匹配的內容。
反向引用:在正則表達式內部引用之前捕獲分組匹配的文本,形式為\num,使用正則表達式([a-z])\1可以表示兩個連續重復的字母,其中num為1是指分組([a-z])的編號,\1表示對其匹配結果的引用。
注意:正則表達式:(\bcat\b)\s+\1,\1是對匹配文本cat的反向引用,但是\1表示匹配cat不含左右邊界的單詞,也會匹配cater,dedicate等單詞。
命名分組
分組可以通過括號編號來調用,但是括號多了容易混淆,因此采用命名分組,對不同分組采取不同的命名,在調用時也會簡單方便。python中命名分組的方式為(?P<name>...),例如對分組(\d{4})命名為(?P<year>\d{4}),調用時使用group(name),如group(year)獲取匹配文本內容。
反向引用:使用了命名分組,在正則表達式中反向引用時,必須使用(?P=name)的記法。
非捕獲分組
前面提到了分組的多重用法,如普通分組、多選結構、引用分組,這些都是需要使用括號構成分組的,一旦構成分組,就會對分組匹配的文本信息進行保存。有一些匹配文本是我們不需要的,我們就可以設置分組為非捕獲分組,格式為(?:...),如(?:\d{4})。在引用分組和非捕獲分組交叉出現時,非捕獲分組不會占用分組編號。