一日一技:正則表達式同一個小括號兩種意思
在Python里面,當我們要從一段正則表達式中提取出一部分內容的時候,我們可以把這部分內容用小括號包起來。例如:從字符串我的密碼123456abc中提取123456abc,我們可以這樣寫正則表達式:
- import re
- s = '我的密碼123456abc'
- password = re.findall('密碼(.*?)$', s)
- print(password)
運行效果如下圖所示:
在這個例子里面,小括號的意思是“分組”。
但是,在正則表達式里面,小括號還有另外一個意思,那就是把幾個符號放在一起,作為一個整體。
例如,還有另一個字符串我的口令123456abc,這里密碼前面是口令,為了使用同一個正則表達式來從這兩個句子里面提取密碼,那么需要表達密碼或口令(.*?)$這個意思。
但如果我們這樣寫:
- 密碼|口令(.*?)$
它實際上表達的意思是密碼令(.*?)$或者密口令(.*?)$。
所以我們需要把(密碼)和口令作為整體來看待。此時,正則表達式本身支持使用括號來表示:
- (密碼|口令)(.*?)$
在正則表達式里面,小括號內部的|左右兩側的多個字符串會作為整體,這樣就能表示密碼(.*?)$或口令(.*?)$了。
但是,正則表達式里面作為整體的小括號,與Python里面用來分組的小括號發生了沖突,于是我們會發現提取出來的內容并不是我們想要的:
可以看到,這里,(密碼|口令)它同時即有正則表達式里面作為整體的功能,又有Python里面分組的功能。于是結果多出來了我們不想要的東西。
那么有什么辦法讓(密碼|口令)只實現正則表達式里面的作為整體的功能,不實現Python里面的分組功能呢?這個時候就需要使用正則表達式里面的一個組合符號?:了。
請大家對比下面三個結果:
可以看到,>.*?<與<(?:.*?)>的作用是一樣的。這就說明,以?:開頭的小括號,它失去了分組的功能。
因此,我們把這個特征用到一開始的例子中:
- >>> import re
- >>> s = '我的密碼123456abc'
- >>> re.findall('(?:密碼|口令)(.*?)$', s)
- ['123456abc']
- >>> s = '我的口令123456abc'
- >>> re.findall('(?:密碼|口令)(.*?)$', s)
- ['123456abc']
運行效果如下圖所示,完成任務:
本文轉載自微信公眾號「未聞Code」,可以通過以下二維碼關注。轉載本文請聯系未聞Code公眾號。