正則表達式(regular expression)是一種用形式化語法描述的文本匹配模式。在需要處理大量文本處理的應用中有廣泛的使用,我沒使用的編輯器,IDE中的搜索常用正則表達式作為搜索模式。玩過*nix系統的都知道如sed,grep,awk這類的命令,他們是非常強大的文本處理工具。幾乎所有的語言都有對正則表達式的支持,有的直接在語法中支持,有的使用擴展庫的形式。python使用的就是擴展庫re。
re.search(pattern,string,flag=0)
import re pattern = "this" text = "Does this text match the pattern?" match = re.search(pattern, text) # 返回一個Match對象 print match.re.pattern # 要匹配的正則表達式"this"print match.string # 匹配的文本"Does this match the pattern?" print match.start() # 匹配的開始位置 5print match.end() # 匹配的結束位置 9
re.compile(pattern,flag=0)
如果程序中頻繁的使用到同一個正則表達式,每次使用的時候都寫一遍正則表達式不僅不高效而且會大大增加出錯的幾率,re提供了compile函數將一個表達式字符串編譯為一個RegexObject。
模塊級函數會維護已編譯表達式的一個緩存,而這個緩存是的大小是有限制的。直接使用已經編譯的表達式可以避免緩存查找的開銷,并且在加載模塊時就會預編譯所有的表達式。
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會返回匹配的單個實例,使用findall會返回所有匹配的不重疊的子串。
import re pattern = 'ab' text = 'abbaaabbbbaaaaaa' re.findall(pattern, text) # 返回['ab', 'ab']
re.finditer(pattern, string, flag=0)
finditer會返回一個迭代器,會生成Match實例,不像findall()返回字符串.
import re pattern = 'ab' text = 'abbaaabbbbaaaaaa' match = re.finditer(pattern, text) for m in match: print m.start() print m.end()
以上的例子會分別輸出兩次匹配結果的起始位置和結束位置。
正則匹配默認采用的是貪婪算法,也就是說會re在匹配的時候會利用盡可能多的輸入,而使用?可以關閉這種貪心行為,只匹配最少的輸入。這之前先說下量詞。
量詞是為了簡化正則表達式的讀寫而定義的,通用的形式是{m,n},這表示匹配的個數至少是m,最多是n,在','之后不能有空格,否則會出錯,并且均為閉區間。
除了之上,還有三個常用的量詞*,?和+
還有^和$,分別表示段或者字符串的開始與結束。
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" 對于一些預定義的字符集可以使用轉義碼可以更加緊湊的表示,re可以識別的轉義碼有3對,6個,分別為三個字母的大小寫,他們的意義是相反的。
如果想指定匹配的內容在文本的相對位置,可以使用錨定,跟轉義碼類似。
import rethe_str = "This is some text -- with punctuation" re.search(r'^/w+', the_str).group(0) # Thisre.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) # 沒有匹配
用組來解析匹配,簡單的說就是在一個正則表達式中有幾個小括號()將匹配的表達式分成不同的組,使用group()函數來獲取某個組的匹配,其中0為整個正則表達式所匹配的內容,后面從1開始從左往右依次獲取每個組的匹配,即每個小括號中的匹配。使用groups()可以獲取所有的匹配內容。
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對分組的語法做了擴展,我們可以對每個分組進行命名,這樣便可以使用名稱來調用。語法:(?P<name>pattern),使用groupdict()可以返回一個包含了組名的字典。
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()方法在使用的時候需要注意,只有在有匹配的時候才會正常運行,否則會拋錯,所以在不能保證有匹配而又要輸出匹配結果的時候,必須做校驗。
在re中可以設置不通的標志,也就是search()和compile()等中都包含的缺省變量flag。使用標志可以進行完成一些特殊的要求,如忽略大小寫,多行搜索等。
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']
新聞熱點
疑難解答
圖片精選