正規表示式是搜尋、替換和解析複雜字串的一種強大而標準的方法,Python中的正則相關的東西全在re模組下。
1 常用的匹配
^匹配字串的開始
$匹配字串的結尾
\b匹配一個單詞的邊界
\d匹配任意數字
\D匹配任意非數字字元
x?匹配一個可選的x(匹配1次或0次x字元)
x*匹配0次或多次x
x+匹配1次或多次x
x{n,m}至少n次,至多m次x
(a|b|c)要麼匹配a,要麼匹配b,要麼匹配c
(x)一般情況下表示一個記憶組,你可以利用re.search函式返回物件的groups()函式來獲取它的值
2 一般用途
#------------------------------------------------------------------------------- # coding: utf-8 # Purpose:正規表示式 # # Author: zdk # # Created: 26/02/2013 # Copyright: (c) zdk 2013 #------------------------------------------------------------------------------- import re if __name__ == '__main__': addr = "100 BROAD ROAD APT.3" print(re.sub("ROAD","RD",addr)) # 100 BRD RD APT.3 print(re.sub(r"\bROAD\b","RD",addr)) # 100 BROAD RD APT.3 pattern = ".*B.*(ROAD)?" print(re.search(pattern,"ROAD")) #None print(re.search(pattern,"B")) #<_sre.SRE_Match object at 0x0230F020><span style="background-color:#FAFAFA;font-family:Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace;font-size:1em;line-height:1.5;"> </span>
(1)re.sub("ROAD","RD",addr) 利用re.sub函式對字串addr進行搜尋,滿足表示式"ROAD"的用“RD”替換
(2)re.sub(r"\bROAD\b","RD",addr) ,“\b”含義是“單詞的邊界”,在Python中,由於字元“\”在字串中必須轉義,這會變得非常麻煩,所以Python用字首r表示字串中的所有字元都不轉義。
(3)re.search(pattern,"ROAD") re模組有一個search函式,該函式有兩個引數,一個是正規表示式,一個是字串,search函式返回一個擁有多種方法可以描述這個匹配的物件,如果沒有發現匹配,則返回None。
3 鬆散正規表示式
上面均是“緊湊”型別的表示式,它比較難以閱讀,即使現在清楚表示式的含義,也不能保證幾個月後還能記得。所以Python允許使用者利用所謂的鬆散正規表示式來完成內聯文件的需要,和一般的表示式有以下兩個方面的主要區別
忽略空白符。空格符、製表符、回車符不匹配它們自身(如果你想在鬆散正規表示式中匹配一個空格符,你不須在它前面新增一個反斜槓符號對它進行轉義)
忽略註釋。和普通的Python程式碼一樣,註釋開始於#符號,結束於行尾。
#鬆散帶有內聯註釋的正規表示式 pattern = """ ^ # begin of string M{0,3} # 0 to 3 M (CM|CD|D?C{0,3}) #CM or CD or D or D 0 to 3 C $ #end of string """ print(re.search(pattern,"MCM",re.VERBOSE)) #<_sre.SRE_Match object at 0x021BAF60> print(re.search(pattern,"M99",re.VERBOSE)) #None
(1)當使用鬆散正規表示式時,最重要的一件事就是:必須傳遞一個額外的引數re.VERBOSE,它是re模組的一個常量,標誌著待匹配的正規表示式是一個鬆散正規表示式。pattern的空格和註釋都是被忽略的,但同時具有更好的可讀性。
4 個例研究:解析電話號碼
必須匹配如下電話號碼:
800-555-1212
800 555 1212
800.555.1212
(800)555-1212
1-800-555-1212
800-555-1212-1234
800-555-1212x1234
800-555-1212 ext.1234
work 1-(800) 555,1212 #1234
格式比較多,我們需要知道的是800為區號,幹線號為555,電話號的其他數字為1212,對於有分機號的,我們需要知道分機號為1234
phonePattern = re.compile(r''' # don't match beginging of string (\d{3}) # 3 digits \D* #any number of non-digits (\d{3}) # 3 digits \D* #any number of non-digits (\d{4}) # 4 digits \D* #any number of non-digits (\d*) #any number of digits ''',re.VERBOSE) print(phonePattern.search('work 1-(800)555.1212 #1234').groups()) #('800', '555', '1212', '1234')
print(phonePattern.search('work 1-(800)555.1212 #1234').groups()) #('800', '555', '1212', '1234')
(1)一個鬆散正規表示式如上, 首先匹配3個數字區號(不一定從第一個字元開始,所以沒有用^),接著後面匹配任意多個非數字的字元,接著匹配3個數字幹線號,接著匹配任意多個非數字的字元,接著匹配4個數字號碼,接著匹配任意多個非數字的字元,接著匹配任意多個數字的分機號,然後用groups函式分組,得到正確的電話號碼。