Python之正則表達式re模組(2)
- 2019 年 12 月 24 日
- 筆記
前言
開始正式介紹Python正則表達式re模組中的內容。R&Python Data Science系列:數據處理(9)–Python之正則表達式re模組(一)搭建好了如何介紹re模組的框架,後面內容會按照正則表達式常用的語法、正則表達式編譯函數compile()、re模組中RegexObject對象常用的方法、re模組中MatchObject實例的方法4部分往框架中填充內容。
5.2 Python之正則表達式re模組
Python中正則表達式使用re模組,re模組中的方法使用正則表達式來匹配字元串。
5.2.1 正則表達式的常用語法
工欲善其事,必先利其器。如何構造正則表達式?正則表達式像其他語言一樣,有自己獨有的語法,掌握其用法,就可以構造需要的正則表達式。常用的正則表達式語法有:
- 特殊字元
- 重複量詞
- 分組與條件或
- 特殊字元
特殊字元為比較特殊的字元,與本身並不匹配,而表示一些特定的匹配,常用的特殊字元有:
語法 |
說明 |
正則表達式實例 |
匹配的字元串 |
匹配成功結果的字元串 |
---|---|---|---|---|
. |
匹配除換行符之外的任意字元 |
r'Fla.' |
'Flash' |
'Flas' |
[] |
1、字符集[],匹配字符集中的一個字元,從左到右匹配直到匹配成功2、字符集[^]表示取反,即只要不是字符集內的字元都可以匹配成功3、"-"表示範圍,當字符集有某種規則,例如[abcd],可以寫成[a-d],[0-5][0-9] 將匹配從 00 到 59 的兩位數字 4、所有特殊字元在[]中都失去原有的意思 |
r'Fl[abc]' |
'Flash' |
'Fla' |
r'Fl[^bcf]' |
'Flash' |
'Fla' |
||
r'Fl[a-c]' |
'Flash' |
'Fla' |
||
r'Fl[+*]' |
'Fl*sh' |
'Fl*' |
||
A |
不在MULTILINE 模式下,A 等價於 ^ ;在 MULTILINE 模式:A 只是匹配字元串首,而 ^ 還可以匹配在換行符之後字元串的任何位置 |
r'AFlash' |
'Flashs' |
'Flash' |
b |
匹配空字元串,匹配單詞的詞首和詞尾,單詞被定義為一個字母數字序列,因此詞尾是用空白符或非字母數字元來表示的 |
r'Flashb |
'Flashs' |
'' |
r'Flashb |
'Flash+' |
'Flash' |
||
B |
與b相反,只在當前位置不在單詞邊界時候匹配 |
r'Flashb |
'Flashs' |
'Flash' |
r'Flashb |
'Flash+' |
'' |
||
d |
匹配單個數字字元0-9,等價於[0-9] |
r'Flashd' |
『Flash7a' |
'Flash7' |
D |
匹配非數字字元,等價於[^0-9] |
r'FlashD' |
『Flasha' |
'Flasha' |
s |
匹配任何空白字元,等價於 [ tnrfv] |
r'Flashs' |
『Flashn' |
'Flashn' |
S |
匹配任何非空白字元,等價於 [^ tnrfv] |
r'FlashS' |
『Flash7' |
'Flash7' |
w |
匹配任何字母數字字元,等價於 [a-zA-Z0-9] |
r'Flashw' |
『Flash7' |
'Flash7' |
W |
匹配任何非字母數字字元,等價 [^a-zA-Z0-9] |
r'FlashW' |
『Flash*' |
'Flash*' |
^ |
匹配行首,在 MULTILINE 模式里,匹配在換行符之後字元串的任何位置 |
r'^Flash' |
'Flashs' |
'Flash' |
$ |
匹配行位,行尾被定義為要麼是字元串尾,要麼是一個換行字元後面的任何位置 |
r's$' |
'Flashs' |
's' |
- 重複量詞
如果想要匹配前一個字元n次,總不能把前一個字元寫n次吧,正則表達式另一個強大的功能是可以指定重複的次數。
語法 |
說明 |
正則表達式實例 |
匹配的字元串 |
匹配成功結果的字元串 |
---|---|---|---|---|
* |
匹配前一字元0次到無限次(最大20億次),貪婪匹配,盡量多的匹配 |
r'Fla*' |
'Flaaa' |
'Flaaa' |
+ |
匹配前一字元1次到無限次(最大20億次),貪婪匹配,盡量多的匹配 |
r'Fla+' |
'Flaaa' |
'Flaaa' |
? |
匹配前一字元0次或者1次,貪婪匹配,盡量多的匹配 |
r'Fla?' |
'Flaaa' |
'Fla' |
{m} |
匹配前一字元m次 |
r'Fla{2}' |
'Flaaa' |
'Flaa' |
{m.n} |
匹配前一字元m次至n次,m是下限,n是上限,m和n可以省略,所以{m,}匹配前一字元m次至無限次,{,n}匹配前一字元0次至n次,貪婪匹配 |
r'Fla{1,2}' |
'Flaaa' |
'Flaa' |
r'Fla{1,}' |
'Flaaa' |
'Flaaa' |
||
r'Fla{,2}' |
'Flaaa' |
'Flaa' |
||
*?和+?和??和{m,n}? |
貪婪匹配變成非貪婪匹配,盡量少的匹配 |
r'Fla*?' |
'Flaaa' |
'Fl' |
r'Fla+?' |
'Flaaa' |
'Fla' |
||
r'Fla??' |
'Flaaa' |
'Fl' |
||
r'Fla{1,2}?' |
'Flaaa' |
'Fla' |
||
r'Fla{1,}?' |
'Flaaa' |
'Fla' |
- 分組與條件或
上面特殊字元以及重複量詞都是只能對前一個字元匹配,如果需要將前面幾個字元作為一個整體(例如匹配以ab開頭的字元串)或者匹配指定無規則字元中的一個(例如匹配以字母a或者b開頭的字元串)。可以使用()來做分組,括弧內的字元為一個整體,使用|表示條件或,滿足分支條件中的任意一種條件時,都會成功匹配。
語法 |
說明 |
正則表達式實例 |
匹配的字元串 |
匹配成功結果的字元串 |
---|---|---|---|---|
| |
or的意思,優先順序很低 |
r'Fl|Wo' |
'FlaWork' |
['Fl', 'Wo'] |
() |
括弧中的字元為一個整體,可以使用量詞或者| |
r'(las)' |
'Flash' |
las' |
r'(la|las)' |
'Flash' |
la' |
註:以上正則表達式的語法,只列出一些常用到的語法,若沒有列出的語法可以參考re–正則表達式操作文檔(https://docs.python.org/zh-cn/3/library/re.html)
5.2.2 編譯正則表達式
已了解正則表達式的常用語法,在Python中如何使用正則表達式呢?re模組提供了一個正則表達式引擎介面,可以將正則表達式編譯成對象並用它們進行匹配。使用re.compile()將正則表達式編譯成RegexObject對象,可以使用編譯標誌修改正則表達式的一些運行方式,如不區分大小寫、多行匹配等。在re模組中標誌有兩種形式:全名與縮寫,如DoTALL和S等價,默認情況下為re.UNICODE標誌,多個標誌通過|來指定,例如re.IGNORECASE|re.UNICODE。
常用的標誌有:
標誌 |
含義 |
---|---|
DOTALL或者S |
使 . 匹配包括換行在內的所有字元 |
IGNORECASE或者I |
使正則表達式忽略大小寫 |
LOCALE或者L |
做本地化識別(locale-aware)匹配 |
MULTILINE或者M |
多行匹配,使每個^在每個回車後,每個$在每個回車前匹配 |
VERBOSE或者X |
該標誌通過給予你更靈活的格式(如跨行、添加註釋)以便你將正則表達式寫得更易於理解。 |
UNICODE或者U |
特殊字符集 w, W, b, B, d, D, s, S 依賴於 Unicode 字元屬性資料庫 |
import rep = re.compile(r'Fla{1,}')p
import rep = re.compile(r'Fla{1,}')p.findall('Flaaa')
使用re.I標誌,忽略大小寫:
import rep = re.compile(r'Fla{1,}', re.I)p
import rep = re.compile(r'Fla{1,}', re.I)p.findall('FlAAA')
使用re.compile()將正則表達式編譯成RegexObject,既然是對象,就有方法可以調用,RegexObject對象常用方法有match()、search()、findall()、finditer()、split()、sub()以及subn()。
RegexObject常用方法 |
|
---|---|
方法/屬性 |
作用 |
match() |
嘗試從字元串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none |
search() |
掃描整個字元串並返回第一個成功的匹配,沒有匹配成功返回None |
findall() |
找到匹配成功的所有子串,並把它們作為一個列表返回,若沒有匹配成功,返回空列表 |
finditer() |
找到匹配成功的所有子串,並把它們作為一個迭代器返回 |
split() |
將字元串在匹配成功的地方分割並生成一個列表, |
sub() |
找到匹配成功的所有子串,並將其用一個不同的字元串替換 |
subn() |
與 sub() 相同,但返回新的字元串和替換次數 |