Python學(xué)習(xí)教程:使用正則表達(dá)式正則表達(dá)式相關(guān)知識(shí)在編寫處理字符串的程序或網(wǎng)頁時(shí),經(jīng)常會(huì)有查找符合某些復(fù)雜規(guī)則的字符串的需要,正則表達(dá)式就是用于描述這些規(guī)則的工具,換句話說正則表達(dá)式是一種工具,它定義了字符串的匹配模式(如何檢查一個(gè)字符串是否有跟某種模式匹配的部分或者從一個(gè)字符串中將與模式匹配的部分提取出來或者替換掉)。如果你在Windows操作系統(tǒng)中使用過文件查找并且在指定文件名時(shí)使用過通配符(*和?),那么正則表達(dá)式也是與之類似的用來進(jìn)行文本匹配的工具,只不過比起通配符正則表達(dá)式更強(qiáng)大,它能更精確地描述你的需求(當(dāng)然你付出的代價(jià)是書寫一個(gè)正則表達(dá)式比打出一個(gè)通配符要復(fù)雜得多,要知道任何給你帶來好處的東西都是有代價(jià)的,就如同學(xué)習(xí)一門編程語言一樣),比如你可以編寫一個(gè)正則表達(dá)式,用來查找所有以0開頭,后面跟著2-3個(gè)數(shù)字,然后是一個(gè)連字號(hào)“-”,最后是7或8位數(shù)字的字符串(像028-12345678或0813-7654321),這不就是國內(nèi)的座機(jī)號(hào)碼嗎。最初計(jì)算機(jī)是為了做數(shù)學(xué)運(yùn)算而誕生的,處理的信息基本上都是數(shù)值,而今天我們在日常工作中處理的信息基本上都是文本數(shù)據(jù),我們希望計(jì)算機(jī)能夠識(shí)別和處理符合某些模式的文本,正則表達(dá)式就顯得非常重要了。今天幾乎所有的編程語言都提供了對正則表達(dá)式操作的支持,Python通過標(biāo)準(zhǔn)庫中的re模塊來支持正則表達(dá)式操作。 我們可以考慮下面一個(gè)問題:我們從某個(gè)地方(可能是一個(gè)文本文件,也可能是網(wǎng)絡(luò)上的一則新聞)獲得了一個(gè)字符串,希望在字符串中找出手機(jī)號(hào)和座機(jī)號(hào)。當(dāng)然我們可以設(shè)定手機(jī)號(hào)是11位的數(shù)字(注意并不是隨機(jī)的11位數(shù)字,因?yàn)槟銢]有見過“25012345678”這樣的手機(jī)號(hào)吧)而座機(jī)號(hào)跟上一段中描述的模式相同,如果不使用正則表達(dá)式要完成這個(gè)任務(wù)就會(huì)很麻煩。 關(guān)于正則表達(dá)式的相關(guān)知識(shí),大家可以閱讀一篇非常有名的博客叫《正則表達(dá)式30分鐘入門教程》,讀完這篇文章后你就可以看懂下面的表格,這是我們對正則表達(dá)式中的一些基本符號(hào)進(jìn)行的扼要總結(jié)。
Python對正則表達(dá)式的支持Python提供了re模塊來支持正則表達(dá)式相關(guān)操作,下面是re模塊中的核心函數(shù)。
下面我們通過一系列的例子來告訴大家在Python中如何使用正則表達(dá)式。 例子1:驗(yàn)證輸入用戶名和QQ號(hào)是否有效并給出對應(yīng)的提示信息。"""驗(yàn)證輸入用戶名和QQ號(hào)是否有效并給出對應(yīng)的提示信息要求:用戶名必須由字母、數(shù)字或下劃線構(gòu)成且長度在6~20個(gè)字符之間,QQ號(hào)是5~12的數(shù)字且首位不能為0"""import redef main(): username = input('請輸入用戶名: ') qq = input('請輸入QQ號(hào): ') # match函數(shù)的第一個(gè)參數(shù)是正則表達(dá)式字符串或正則表達(dá)式對象# 第二個(gè)參數(shù)是要跟正則表達(dá)式做匹配的字符串對象m1 = re.match(r'^[0-9a-zA-Z_]{6,20}$', username) if not m1: print('請輸入有效的用戶名.') m2 = re.match(r'^[1-9]\d{4,11}$', qq) if not m2: print('請輸入有效的QQ號(hào).') if m1 and m2: print('你輸入的信息是有效的!')if __name__ == '__main__': main()
例子2:從一段文字中提取出國內(nèi)手機(jī)號(hào)碼。下面這張圖是截止到2017年底,國內(nèi)三家運(yùn)營商推出的手機(jī)號(hào)段。 import redef main(): # 創(chuàng)建正則表達(dá)式對象 使用了前瞻和回顧來保證手機(jī)號(hào)前后不應(yīng)該出現(xiàn)數(shù)字pattern = re.compile(r'(?<=\D)1[34578]\d{9}(?=\D)') sentence = ''' 重要的事情說8130123456789遍,我的手機(jī)號(hào)是13512346789這個(gè)靚號(hào), 不是15600998765,也是110或119,王大錘的手機(jī)號(hào)才是15600998765。 '''# 查找所有匹配并保存到一個(gè)列表中mylist = re.findall(pattern, sentence) print(mylist) print('--------華麗的分隔線--------') # 通過迭代器取出匹配對象并獲得匹配的內(nèi)容for temp in pattern.finditer(sentence): print(temp.group()) print('--------華麗的分隔線--------') # 通過search函數(shù)指定搜索位置找出所有匹配m = pattern.search(sentence) while m: print(m.group()) m = pattern.search(sentence, m.end())if __name__ == '__main__': main()
例子3:替換字符串中的不良內(nèi)容import redef main(): sentence = '你丫是傻叉嗎? 我操你大爺?shù)? Fuck you.'purified = re.sub('[操肏艸]|fuck|shit|傻[比屄逼叉缺吊屌]|煞筆', '*', sentence, flags=re.IGNORECASE) print(purified) # 你丫是*嗎? 我*你大爺?shù)? * you.if __name__ == '__main__': main()
例子4:拆分長字符串import redef main(): poem = '窗前明月光,疑是地上霜。舉頭望明月,低頭思故鄉(xiāng)。'sentence_list = re.split(r'[,。, .]', poem) while '' in sentence_list: sentence_list.remove('') print(sentence_list) # ['窗前明月光', '疑是地上霜', '舉頭望明月', '低頭思故鄉(xiāng)']if __name__ == '__main__': main() 后話如果要從事爬蟲類應(yīng)用的開發(fā),那么正則表達(dá)式一定是一個(gè)非常好的助手,因?yàn)樗梢詭椭覀冄杆俚膹木W(wǎng)頁代碼中發(fā)現(xiàn)某種我們指定的模式并提取出我們需要的信息,當(dāng)然對于初學(xué)者來收,要編寫一個(gè)正確的適當(dāng)?shù)恼齽t表達(dá)式可能并不是一件容易的事情(當(dāng)然有些常用的正則表達(dá)式可以直接在網(wǎng)上找找),所以實(shí)際開發(fā)爬蟲應(yīng)用的時(shí)候,有很多人會(huì)選擇Beautiful Soup或Lxml來進(jìn)行匹配和信息的提取,前者簡單方便但是性能較差,后者既好用性能也好,但是安裝稍嫌麻煩,這些內(nèi)容我們會(huì)在后期的爬蟲專題中為大家介紹。 |
|