Python學習 【四】:正則表達式
一、正則表達式基礎
1.簡介
正則表達式並不是Python的一部分。正則表達式是用於處理字符串的強大工具,擁有自己獨特的語法以及一個獨立的處理引擎,效率上可能不如str自帶的方法,但功能十分強大。得益於這一點,在提供了正則表達式的語言裏,正則表達式的語法都是一樣的,區別只在於不同的編程語言實現支持的語法數量不同;但不用擔心,不被支持的語法通常是不常用的部分。如果已經在其他語言裏使用過正則表達式,只需要簡單看一看就可以上手了。
正則表達式的大致匹配過程是:依次拿出表達式和文本中的字符比較,如果每一個字符都能匹配,則匹配成功;一旦有匹配不成功的字符則匹配失敗。如果表達式中有量詞或邊界,這個過程會稍微有一些不同,但也是很好理解。
下圖列出了Python支持的正則表達式元字符和語法(圖片來自網絡):
2、細節註意
(1)貪婪匹配和非貪婪匹配
當我們使用 * + ?號的時候默認采取貪婪匹配(即匹配最大個數),當在這些符號之後再加一個 ?或者直接使用{m,n}采取非貪婪匹配(加?表示按最小次數,{}表示按需匹配)
(2)匹配模式
#匹配模式 re.I #匹配中大小寫不敏感 re.L #使預定字符類 \w \W \b \B \s \S 取決於當前區域設定 re.M #多行匹配,影響^和$符號 re.S #包含換行在內的所有字符,影響 . 元字符
re.U #使預定字符類 \w \W \b \B \s \S \d \D 取決於unicode定義的字符屬性
re.X #詳細模式。這個模式下正則表達式可以是多行,忽略空白字符,並可以加入註釋。
(3)原生字符串
與大多數編程語言相同,正則表達式裏使用"\"作為轉義字符,這就可能造成反斜杠困擾。假如你需要匹配文本中的字符"\",那麽使用編程語言表示的正則表達式裏將需要4個反斜杠"\\\\":前兩個和後兩個分別用於在編程語言裏轉義成反斜杠,轉換成兩個反斜杠後再在正則表達式裏轉義成一個反斜杠。Python裏的原生字符串很好地解決了這個問題,這個例子中的正則表達式可以使用r"\\"表示。同樣,匹配一個數字的"\\d"可以寫成r"\d"。有了原生字符串,你再也不用擔心是不是漏寫了反斜杠,寫出來的表達式也更直觀。
二、re模塊的使用
1、re中的函數
re.match(pattern, string, flags = 0)#查找字符串最前面符合的子串,返回match對象 #flags表示匹配模式 re.search(pattern, string, flags = 0) #找到一個符合的子串,返回match對象 re.findall(pattern, string, flags = 0) #找到所有符合的子串,返回列表 re.sub(pattern, repl, string, max = 0) #替換字符串中符合的子串,max表示替換的次數 re.subn #替換後還得到替換的次數 re.compile(pattern) #將規則字符串編譯到Pattern對象中,可重復使用,是Pattern類的工廠方法 re.finditer #生成叠代對象
在這過程中,函數返回了match對象和pattern對象,我們來看一下這些類。
#屬性 string: 匹配時使用的文本。 re: 匹配時使用的Pattern對象。 pos: 文本中正則表達式開始搜索的索引。值與Pattern.match()和Pattern.seach()方法的同 名參數相同。 endpos: 文本中正則表達式結束搜索的索引。值與Pattern.match()和Pattern.seach()方法的同名參數相同。 lastindex: 最後一個被捕獲的分組在文本中的索引。如果沒有被捕獲的分組,將為None。 lastgroup: 最後一個被捕獲的分組的別名。如果這個分組沒有別名或者沒有被捕獲的分組,將為None。 #方法 group([group1, …]): 獲得一個或多個分組截獲的字符串;指定多個參數時將以元組形式返回。group1可以使用編號也可以使用別名;編號0代表整個匹配的子串;不填寫參數時,返回group(0);沒有截獲字符串的組返回None;截獲了多次的組返回最後一次截獲的子串。 groups([default]): 以元組形式返回全部分組截獲的字符串。相當於調用group(1,2,…last)。default表示沒有截獲字符串的組以這個值替代,默認為None。 groupdict([default]): 返回以有別名的組的別名為鍵、以該組截獲的子串為值的字典,沒有別名的組不包含在內。default含義同上。 start([group]): 返回指定的組截獲的子串在string中的起始索引(子串第一個字符的索引)。group默認值為0。 end([group]): 返回指定的組截獲的子串在string中的結束索引(子串最後一個字符的索引+1)。group默認值為0。 span([group]): 返回(start(group), end(group))。 expand(template): 將匹配到的分組代入template中然後返回。template中可以使用\id或\g<id>、\g<name>引用分組,但不能使用編號0。\id與\g<id>是等價的;但\10將被認為是第10個分組,如果你想表達\1之後是字符‘0‘,只能使用\g<1>0。Match對象
#Pattern對象是一個編譯好的正則表達式,通過Pattern提供的一系列方法可以對文本進行匹配查找。 #Pattern不能直接實例化,必須使用re.compile()進行構造。 #Pattern提供了幾個可讀屬性用於獲取表達式的相關信息: pattern: 編譯時用的表達式字符串。 flags: 編譯時用的匹配模式。數字形式。 groups: 表達式中分組的數量。 groupindex: 以表達式中有別名的組的別名為鍵、以該組對應的編號為值的字典,沒有別名的組不包含在內。Pattern對象
2、如何使用
1 #導入re模塊 2 import re 3 4 #生成pattern對象 5 pa = re.compile(r‘zss‘) 6 7 ma = pa.search(‘hello zss world!‘) 8 9 if ma: 10 print(ma.group())#通過group函數得到match對象中的元素 11 12 #out# 13 #zss
Python通過re模塊提供對正則表達式的支持。使用re的一般步驟是先將正則表達式的字符串形式編譯為Pattern實例,然後使用Pattern實例處理文本並獲得匹配結果(一個Match實例),最後使用Match實例獲得信息,進行其他的操作。
三、實例
1、ip地址檢測
#!/usr/bin/env python import re def IPTest(ipstr): #創建正則規則字符串 regexstr = r‘(([10]?\d?\d|2[0-4]\d|25[0-5])\.){3}([10]?\d?\d|2[0-4]\d|25[0-5]) pa = re.compile(regexstr) #找出符合規則的叠代對象 ips = pa.finditer(ipstr) if ips: for ip in ips: print(ma.group()) else: print(error!) return 0 def main(): ip = ‘192.168.1.1zss245.255.234zsssss1.1.1.1‘ IPTest(ip main() #運行結果: #192.186.1.1 #245.255.234.1 #1.1.1.1
我們來分析一下規則字符串regexstr:
Python學習 【四】:正則表達式