作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝!
我將從Regex開始講Python的標準庫。Regex是文文書處理中常用的工具,而且不需要額外的系統知識或經驗。我們會把系統相關的包放在後面講解。
Regex(regular expression)主要功能是從字串(string)中通過特定的模式(pattern),搜尋想要找到的內容。
1. Regex文法
之前,我們簡介了字串相關的處理函數。我們可以通過這些函數實現簡單的搜尋功能,比如說從字串“I love you”中搜尋是否有“you”這一子字串。但有些時候,我們只是模糊地知道我們想要找什麼,而不能具體說出我是在找“you”,比如說,我想找出字串中包含的數字,這些數字可以是0到9中的任何一個。這些模糊的目標可以作為資訊寫入Regex,傳遞給Python,從而讓Python知道我們想要找的是什麼。
(官方documentation)
在Python中使用Regex需要標準庫中的一個包re。
import rem = re.search('[0-9]','abcd4ef')print(m.group(0))
re.search()接收兩個參數,第一個'[0-9]'就是我們所說的Regex,它告訴Python的是,“聽著,我從字串想要找的是從0到9的一個數字字元”。
re.search()如果從第二個參數找到符合要求的子字串,就返回一個對象m,你可以通過m.group()的方法查看搜尋到的結果。如果沒有找到符合要求的字元,re.search()會返回None。
如果你熟悉Linux或者Perl, 你應該已經熟悉Regex。當我們開啟Linux shell的時候,可以用Regex去尋找或著刪除我們想要的檔案,比如說:
$rm book[0-9][0-9].txt
這就是要刪除類似於book02.txt的檔案。book[0-9][0-9].txt所包含的資訊是,以book開頭,後面跟兩個數字字元,之後跟有".txt"的檔案名稱。如果不合格檔案名稱,比如說:
bo12.txt
book1.txt
book99.text
都不會被選中。
Perl中內建有Regex的功能,據說是所有Regex系統中最強的,這也是Perl成為系統管理員利器的一個原因。
2. Regex的函數
m = re.search(pattern, string) # 搜尋整個字串,直到發現符合的子字串。m = re.match(pattern, string) # 從頭開始檢查字串是否符合Regex。必須從字串的第一個字元開始就相符。
可以從這兩個函數中選擇一個進行搜尋。上面的例子中,我們如果使用re.match()的話,則會得到None,因為字串的起始為‘a’, 不符合'[0-9]'的要求。
對於返回的m, 我們使用m.group()來調用結果。(我們會在後面更詳細解釋m.group())
我們還可以在搜尋之後將搜尋到的子字串進行替換:
str = re.sub(pattern, replacement, string)
# 在string中利用正則變換pattern進行搜尋,對於搜尋到的字串,用另一字串replacement替換。返回替換後的字串。
此外,常用的Regex函數還有
re.split() # 根據Regex分割字串, 將分割後的所有子字串放在一個表(list)中返回
re.findall() # 根據Regex搜尋字串,將所有符合的子字串放在一給表(list)中返回
(在熟悉了上面的函數後,可以看一下re.compile(),以便於提高搜尋效率。)
3. 寫一個Regex
關鍵在於將資訊寫成一個Regex。我們先看Regex的常用文法:
1)單個字元:
. 任意的一個字元
a|b 字元a或字元b
[afg] a或者f或者g的一個字元
[0-4] 0-4範圍內的一個字元
[a-f] a-f範圍內的一個字元
[^m] 不是m的一個字元
\s 一個空格
\S 一個非空格
\d [0-9]
\D [^0-9]
\w [0-9a-zA-Z]
\W [^0-9a-zA-Z]
2)重複
緊跟在單個字元之後,表示多個這樣類似的字元
* 重複 >=0 次
+ 重複 >=1 次
? 重複 0或者1 次
{m} 重複m次。比如說 a{4}相當於aaaa,再比如說[1-3]{2}相當於[1-3][1-3]
{m, n} 重複m到n次。比如說a{2, 5}表示a重複2到5次。小於m次的重複,或者大於n次的重複都不符合條件。
正則表達 相符的字串舉例
[0-9]{3,5} 9678
a?b b
a+b aaaaab
3) 位置
^ 字串的起始位置
$ 字串的結尾位置
正則表達 相符的字串舉例 不相符字串
^ab.*c$ abeec cabeec (如果用re.search(), 將無法找到。)
4)返回控制
我們有可能對搜尋的結果進行進一步精簡資訊。比如下面一個Regex:
output_(\d{4})
該Regex用括弧()包圍了一個小的Regex,\d{4}。 這個小的Regex被用於從結果中篩選想要的資訊(在這裡是四位元字)。這樣被括弧圈起來的Regex的一部分,稱為群(group)。
我們可以m.group(number)的方法來查詢群。group(0)是整個正則表達的搜尋結果,group(1)是第一個群……
import rem = re.search("output_(\d{4})", "output_1986.txt")print(m.group(1))
我們還可以將群命名,以便更好地使用m.group查詢:
import rem = re.search("output_(?P<year>\d{4})", "output_1986.txt") #(?P<name>...) 為group命名print(m.group("year"))
4. 練習
有一個檔案,檔案名稱為output_1981.10.21.txt
。下面使用Python: 讀取檔案名稱中的日期時間資訊,並找出這一天是周幾。將檔案改名為output_YYYY-MM-DD-W.txt (YYYY:四位的年,MM:兩位的月份,DD:兩位的日,W:一位的周幾,並假設周一為一周第一天)
總結:
re.search() re.match() re.sub() re.findall()
Regex構成方法