在Python中使用正則表達(dá)式的方法
正則表達(dá)式(regular expression)是一種用形式化語(yǔ)法描述的文本匹配模式。在需要處理大量文本處理的應(yīng)用中有廣泛的使用,我沒使用的編輯器,IDE中的搜索常用正則表達(dá)式作為搜索模式。玩過*nix系統(tǒng)的都知道如sed,grep,awk這類的命令,他們是非常強(qiáng)大的文本處理工具。幾乎所有的語(yǔ)言都有對(duì)正則表達(dá)式的支持,有的直接在語(yǔ)法中支持,有的使用擴(kuò)展庫(kù)的形式。python使用的就是擴(kuò)展庫(kù)re。
re.search(pattern,string,flag=0)
每個(gè)Match對(duì)象包括相關(guān)的匹配信息:原字符串、正則表達(dá)式和匹配的文本在字符串中的位置。
import re pattern = "this" text = "Does this text match the pattern?" match = re.search(pattern, text) # 返回一個(gè)Match對(duì)象 print match.re.pattern # 要匹配的正則表達(dá)式"this" print match.string # 匹配的文本"Does this match the pattern?" print match.start() # 匹配的開始位置 5 print match.end() # 匹配的結(jié)束位置 9
re.compile(pattern,flag=0)
如果程序中頻繁的使用到同一個(gè)正則表達(dá)式,每次使用的時(shí)候都寫一遍正則表達(dá)式不僅不高效而且會(huì)大大增加出錯(cuò)的幾率,re提供了compile函數(shù)將一個(gè)表達(dá)式字符串編譯為一個(gè)RegexObject。
模塊級(jí)函數(shù)會(huì)維護(hù)已編譯表達(dá)式的一個(gè)緩存,而這個(gè)緩存是的大小是有限制的。直接使用已經(jīng)編譯的表達(dá)式可以避免緩存查找的開銷,并且在加載模塊時(shí)就會(huì)預(yù)編譯所有的表達(dá)式。
import re regex = re.compile("this") text = "Does this text match the pattern?" match = regex.search(text) if match: print "match" match.group(0) #返回匹配的字符串 else: print "not match"
re.findall(pattern, string, flag=0)
使用search會(huì)返回匹配的單個(gè)實(shí)例,使用findall會(huì)返回所有匹配的不重疊的子串。
import re pattern = 'ab' text = 'abbaaabbbbaaaaaa' re.findall(pattern, text) # 返回['ab', 'ab']
re.finditer(pattern, string, flag=0)
finditer會(huì)返回一個(gè)迭代器,會(huì)生成Match實(shí)例,不像findall()返回字符串.
import re pattern = 'ab' text = 'abbaaabbbbaaaaaa' match = re.finditer(pattern, text) for m in match: print m.start() print m.end()
以上的例子會(huì)分別輸出兩次匹配結(jié)果的起始位置和結(jié)束位置。
正則匹配默認(rèn)采用的是貪婪算法,也就是說會(huì)re在匹配的時(shí)候會(huì)利用盡可能多的輸入,而使用?可以關(guān)閉這種貪心行為,只匹配最少的輸入。這之前先說下量詞。
量詞是為了簡(jiǎn)化正則表達(dá)式的讀寫而定義的,通用的形式是{m,n},這表示匹配的個(gè)數(shù)至少是m,最多是n,在','之后不能有空格,否則會(huì)出錯(cuò),并且均為閉區(qū)間。
- {n} 之前的元素必須出現(xiàn)n次
- {m,n} 之前元素最少出現(xiàn)m次,最多n次
- {m,} 之前的元素最少出現(xiàn)m次,無上限
- {0,n} 之前的元素可以不出現(xiàn),也可以出現(xiàn),出現(xiàn)的話最多出現(xiàn)n次
除了之上,還有三個(gè)常用的量詞*,?和+
- * 等價(jià)于{0,}
- + 等價(jià)于{1,}
- \? 等價(jià)于{0,1}
還有^和$,分別表示段或者字符串的開始與結(jié)束。
import re re.search("^travell?er$", "traveler") # True re.search("^travell?er$", "traveller") # True re.search("^ab\*", "abbbbbbb") # True,返回"abbbbbbb" re.search("^ab\*?", "abbbbbbb") # True,返回"a" re.search("^ab+", "abbbbbbb") # True,返回"abbbbbbb" re.search("^ab+?", "abbbbbbb") # True,返回"ab"
對(duì)于一些預(yù)定義的字符集可以使用轉(zhuǎn)義碼可以更加緊湊的表示,re可以識(shí)別的轉(zhuǎn)義碼有3對(duì),6個(gè),分別為三個(gè)字母的大小寫,他們的意義是相反的。
- \d : 一個(gè)數(shù)字
- \D : 一個(gè)非數(shù)字
- \w : 字母或者數(shù)字
- \W : 非字母,非數(shù)字
- \s : 空白符(制表符,空格,換行符等)
- \S : 非空白符
如果想指定匹配的內(nèi)容在文本的相對(duì)位置,可以使用錨定,跟轉(zhuǎn)義碼類似。
- ^ 字符或行的開始
- $ 字符或行的結(jié)束
- \A 字符串的開始
- \Z 字符串結(jié)束
- \b 一個(gè)單詞開頭或者末尾的空串
- \B 不在一個(gè)單詞開頭或末尾的空串
import re the_str = "This is some text -- with punctuation" re.search(r'^\w+', the_str).group(0) # This re.search(r'\A\w+', the_str).group(0) # This re.search(r'\w+\S*$', the_str).group(0) # punctuation re.search(r'\w+\S*\Z', the_str).group(0) # punctuation re.search(r'\w*t\W*', the_str).group(0) # text -- re.search(r'\bt\w+', the_str).group(0) # text re.search(r'\Bt*\B', the_str).group(0) # 沒有匹配
用組來解析匹配,簡(jiǎn)單的說就是在一個(gè)正則表達(dá)式中有幾個(gè)小括號(hào)()將匹配的表達(dá)式分成不同的組,使用group()函數(shù)來獲取某個(gè)組的匹配,其中0為整個(gè)正則表達(dá)式所匹配的內(nèi)容,后面從1開始從左往右依次獲取每個(gè)組的匹配,即每個(gè)小括號(hào)中的匹配。使用groups()可以獲取所有的匹配內(nèi)容。
import re the_str = "--aabb123bbaa" pattern = r'(\W+)([a-z]+)(\d+)(\D+)' match = re.search(pattern, the_str) match.groups() # ('--', 'aabb', '123', 'bbaa') match.group(0) # '--aabb123bbaa' match.group(1) # '--' match.group(2) # 'aabb' match.group(3) # '123' match.group(4) # 'bbaa'
python對(duì)分組的語(yǔ)法做了擴(kuò)展,我們可以對(duì)每個(gè)分組進(jìn)行命名,這樣便可以使用名稱來調(diào)用。語(yǔ)法:(?P<name>pattern),使用groupdict()可以返回一個(gè)包含了組名的字典。
import re the_str = "--aabb123bbaa" pattern = r'(?P<not_al_and_num>\W+)(?P<al>[a-z]+)(?P<num>\d+)(?P<not_num>\D+)' match = re.search(pattern, the_str) match.groups() # ('--', 'aabb', '123', 'bbaa') match.groupdict() # {'not_al_and_num': '--', 'not_num': 'bbaa', 'num': '123', 'al': 'aabb'} match.group(0) # '--aabb123bbaa' match.group(1) # '--' match.group(2) # 'aabb' match.group(3) # '123' match.group(4) # 'bbaa' match.group('not_al_and_num') # '--' match.group('al') # 'aabb' match.group('num') # '123' ' match.group('not_num') # 'bbaa'
以上的group()方法在使用的時(shí)候需要注意,只有在有匹配的時(shí)候才會(huì)正常運(yùn)行,否則會(huì)拋錯(cuò),所以在不能保證有匹配而又要輸出匹配結(jié)果的時(shí)候,必須做校驗(yàn)。
在re中可以設(shè)置不通的標(biāo)志,也就是search()和compile()等中都包含的缺省變量flag。使用標(biāo)志可以進(jìn)行完成一些特殊的要求,如忽略大小寫,多行搜索等。
import re the_str = "this Text" re.findall(r'\bt\w+', the_str) # ['this'] re.findall(r'\bt\w+', the_str, re.IGNORECASE) # ['this', 'Text']
相關(guān)文章
PyTorch一小時(shí)掌握之a(chǎn)utograd機(jī)制篇
這篇文章主要介紹了PyTorch一小時(shí)掌握之a(chǎn)utograd機(jī)制篇,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09Python Pygame實(shí)戰(zhàn)之趣味籃球游戲的實(shí)現(xiàn)
這篇文章主要為大家分享了一個(gè)基于Python和Pygame實(shí)現(xiàn)的一個(gè)趣味籃球游戲,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下2022-04-04Python的Flask框架中實(shí)現(xiàn)登錄用戶的個(gè)人資料和頭像的教程
這篇文章主要介紹了Python的Flask框架中實(shí)現(xiàn)登錄用戶的個(gè)人資料和頭像的教程,這也是各個(gè)web框架的最基本功能之一,需要的朋友可以參考下2015-04-04Python庫(kù)textract提取各種文檔類型中文本數(shù)據(jù)
Python的textract庫(kù)是一個(gè)強(qiáng)大的工具,它可以從各種文檔類型中提取文本數(shù)據(jù),無論是PDF、Word文檔、圖片還是其他格式的文件,textract都可以輕松地將文本提取出來,本文將詳細(xì)介紹textract的功能和用法,并提供豐富的示例代碼來幫助大家深入了解2024-01-01云原生Docker部署Django和mysql項(xiàng)目全過程
最近在學(xué)習(xí)用docker部署Django項(xiàng)目,經(jīng)過百折不撓的鼓搗,終于將項(xiàng)目部署成功,下面這篇文章主要給大家介紹了關(guān)于云原生Docker部署Django和mysql項(xiàng)目的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12零基礎(chǔ)寫python爬蟲之爬蟲的定義及URL構(gòu)成
俗話說工欲善其事必先利其器,作為本系列文章的第一篇,我們同樣也需要先利其器,先把爬蟲的定義以及寫爬蟲所需要的基礎(chǔ)知識(shí)先介紹給大家。2014-11-11python人人網(wǎng)登錄應(yīng)用實(shí)例
這篇文章主要介紹了python人人網(wǎng)登錄應(yīng)用實(shí)例,是一個(gè)非常實(shí)用的技巧,需要的朋友可以參考下2014-09-09深入淺析Python中l(wèi)ist的復(fù)制及深拷貝與淺拷貝
這篇文章主要介紹了Python中l(wèi)ist的復(fù)制及深拷貝與淺拷貝及區(qū)別解析 ,需要的朋友可以參考下2018-09-09Python使用jpype模塊調(diào)用jar包過程解析
這篇文章主要介紹了Python使用jpype模塊調(diào)用jar包過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07