《零基礎入門學習Python》筆記 第058講:論一隻爬蟲的自我修養6:正則表達式2
上一節課我們通過一個例子(匹配ip 地址)讓大家初步了解到正則表達式的魔力,也讓大家充分了解到學習正則表達式是一個相對比較困難的事情。所以這一節課我們將繼續學習正則表達式的語法。
我們依稀還記得在Python中,正則表達式是以字符串的形式來描述的,正則表達式的強大之處在於特殊符號的應用,我們上節課舉了例子,例如點號(.),在正則表達式中表示匹配除了換行符之外的任何字符,它就是一個特殊的字符。正是這些特殊符號,使得一個正則表達式可以匹配一個複雜的規則,而不僅僅是匹配一個字符串,如果你只需要匹配一個字符串,那用find() 方法就可以了。
這里羅列了python3 所支持的所有正則表達式的特殊符號以及具體的含義,在難以理解的地方,用斜體舉了例子給大家看,方便大家理解,大家可以將這個文章收藏起來,以後用到的時候查詢就可以了,切記不要死記硬背,因為根本背不住,如果背錯了更扎心。
大家看到這裡,可能就會犯嘀咕了:“好歹我也是見過世面的人啊,為了查找一個字符串,有必要掌握這麼多規則嗎?”。
實話說,沒必要。我這裡只是給大家做一個總結,我們正常使用的情況下,只是使用這裡的一小部分,另外一大部分只是為了應對突發情況而準備的。例如某一天,你心血來潮,想為你的規則再增加複雜一點的規則,那麼這裡邊正則表達式就可以應付自如了。一定要記住的是,這裡面的東西不要去背,多做練習才是重要的啊。你掌握的東西才是你的,背下來的東西過兩天就不是你的了。
特殊符號是由兩部分組成的,一部分是元字符。(例如我們上節課講的點號(.),方括號([]),反斜杠(\)等)。
所有的元字符包括:. ^ $ * + ? { } [ ] \ | ( )
另一部分就是反斜杠加上普通符號組成的特殊符號,它擁有特殊的含義。
首先來談談元字符:
點號(.):是匹配除了換行符之外的任何字符。
| :就相當於邏輯或,學過C語言的同學們都知道,這就是按位或。A|B 表示匹配正則表達式A或者B
例如:
托字符(^):定位匹配,匹配字符串的開始位置(即確定一個位置)。
例如:
跟托字符(^)對應的就是美元符號($),$ 匹配輸入字符串的結束位置.
我們剛剛提到了值組,就是用小括號括起來的,我們上節課也用過了,用小括號括起來跟數學的括號是一樣的,把一個東西當做一個整體,那麼就把它括起來。
接下來是史上最困難、最複雜的反斜杠(\),反斜杠在正則表達式中應用是最廣泛的,它既可以將一個普通的字符變為特殊字符(這部分內容下節課繼續講解),同時也可以解除元字符的特殊功能,這在上節課已經講過,例如\. 匹配的就不是除換行符之外的任何字符了,他匹配的就是一個點(.)了。
如果在反斜杠後面加的是數字,那麼還有兩種表示方案:
①如果跟著的數字是1~99,就表示引用序號對應的值組所匹配的字符串,其中序號所對應的值組:為\ 前面的值組,\序號必須在對應的值組的正後面,序號為第幾個值組。
例如:
上面的(Python)是第一個值組(序號是從1開始計算的,因為0表示一個八進制數),所以\1,且\1表示Python,其實r'(Python)\1'就等於' PythonPython'。
並不是要求全部都要是值組,是要求\序號匹配的是值組:
例如:字符0 對應的十進制數為48,對應的八進制數為60,這裡要三位數,就是060,所以:
接下來要介紹的元字符是中括號([ ]),這是生成一個字符類,事實上,字符類就是一個字符集合的意思,另外,值的注意的是:被中括號包含在裡面的元字符都會失去特殊功能,就像反斜杠加上一個元字符是一樣的,舉例:
字符類的意思就是將它裡面的內容都當做普通的字符看待,除了幾個特殊的字符:
①小橫槓(-),我們用它表示範圍,我們上節課講過,這節課我們講一個其他的方法:re.findall()
所有的元字符包括:. ^ $ * + ? { } [ ] \ | ( )
re.findall
在字符串中找到正則表達式所匹配的所有子串,並把它們作為一個列表返回。
re.findall(pattern, string, flags=0)
參數:
參數 描述
pattern 匹配的正則表達式
string 要匹配的字符串。
flags 標誌位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。
findall 和search 相比,似乎更符合我們的需求,但是當遇到值組時,findall 也會有陷阱,我們後面會講解。
②反斜杠(\),把反斜杠放在字符類[ ]中,它也不是表示本身,這樣會報錯,
反斜杠在字符類裡,表示Python 字符串的轉義符。
在字符串裡,我們都知道\n 表示回車的意思,所以:
③托字符^,在字符類[ ]裡,表示'除了'(取反)的意思,但是要注意的是,這個托字符^必須放在最前面:
如果放在後面,就是表示匹配它本身:
最後要介紹的元字符是用於做重複的事情,例如我們上節課講到的大括號{ },如{M,N}(要求M,N均為非負整數,且M<=N)表示前面的內容匹配M~N次。
在正則表達式中,需要注意的是,大家在寫編程的時候,可能會注意美觀,可能會多加一些空格,但是在正則表達式裡面,你千萬不能加空格,例如:
因為空格會被解析為一個正則表達式。
最後,我們來談一下幾個特殊的:
①星號(*):匹配前面的子表達式零次或多次,等價於{0,}
②加號(+):匹配前面的子表達式一次或多次,等價於{1,}
③問號(?):匹配前面的子表達式零次或一次,等價於{0,1}
在正則表達式中,如果實現條件一樣,推薦大家使用左邊的* + ?這三個,不要使用大括號{ },因為:首先,星號、加號、問號更加簡潔;其次,正則表達式內部會對這三個符號進行優化,效率會比使用大括號要高一些。
最後,我們來談一下貪婪和非貪婪。
關於我們這個重複的操作,有一點需要注意的就是:正則表達式默認是啟用貪婪的模式來進行匹配的,那什麼是貪婪呢?貪婪就是貪心,也就是說,只要在符合的條件下,它會盡可能多的去匹配,例如前面的re.search(r'(Python){1,5}', 'I love PythonPythonPython') 就會直接匹配到3個Python。
我們來看一個現實中的案例。假設我們想匹配<html>
<.+> 表示以< 開頭,以> 結尾,重複. 號1次或多次。最後匹配了字符串全部。很明顯,這不是我們想要的結果。
因為貪婪會在條件符合的情況下盡可能多的去匹配,既然是這樣,我們就必須啟用非貪婪模式才可以,那麼非貪婪模式怎麼樣啟用呢?
很簡單,在表示重複的元字符後面再加上一個問號,這時候,問號就不代表0次或1次了,而是表示啟用非貪婪模式:
好了,到這裡,正則表達式的所有元字符我麼就講解完畢了,大家課後一定要勤加練習。
在字符串中找到正則表達式所匹配的所有子串,並把它們作為一個列表返回。
re.findall(pattern, string, flags=0)
參數:
| 參數 | 描述 |
|---|---|
| pattern | 匹配的正則表達式 |
| string | 要匹配的字符串。 |
| flags | 標誌位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。 |
0 留言:
發佈留言