一丶正則表達式
正則表達式自己是一種小型的、高度專業化的編程語言,它並非Python的一部分。正則表達式是用於處理字符串的強大工具,擁有本身獨特的語法以及一個獨立的處理引擎,效率上可能不如str自帶的方法,但功能十分強大。得益於這一點,在提供了正則表達式的語言裏,正則表達式的語法都是同樣的,區別只在於不一樣的編程語言實現支持的語法數量不一樣;但不用擔憂,不被支持的語法一般是不經常使用的部分。若是已經在其餘語言裏使用過正則表達式,只須要簡單看一看就能夠上手了。而在python中,經過內嵌集成re模塊,程序員們能夠直接調用來實現正則匹配。正則表達式模式被編譯成一系列的字節碼,而後由用C編寫的匹配引擎執行。python
正則表達式的大體匹配過程是:依次拿出表達式和文本中的字符比較,若是每個字符都能匹配,則匹配成功;一旦有匹配不成功的字符則匹配失敗。若是表達式中有量詞或邊界,這個過程會稍微有一些不一樣,但也是很好理解的程序員
正則表達式一般用於在文本中查找匹配的字符串。Python裏數量詞默認是貪婪的(在少數語言裏也多是默認非貪婪),老是嘗試匹配儘量多的字符;非貪婪的則相反,老是嘗試匹配儘量少的字符。例如:正則表達式"ab"若是用於查找"abbbc",將找到"abbb"。而若是使用非貪婪的數量詞"ab?",將找到"a"。
與大多數編程語言相同,正則表達式裏使用""做爲轉義字符,這就可能形成反斜槓困擾。假如你須要匹配文本中的字符"",那麼使用編程語言表示的正則表達式裏將須要4個反斜槓"\":前兩個和後兩個分別用於在編程語言裏轉義成反斜槓,轉換成兩個反斜槓後再在正則表達式裏轉義成一個反斜槓。Python裏的原生字符串很好地解決了這個問題,這個例子中的正則表達式可使用r""表示。一樣,匹配一個數字的"\d"能夠寫成r"\d"。有了原生字符串,你不再用擔憂是否是漏寫了反斜槓,寫出來的表達式也更直觀。正則表達式
正則表達式提供了一些可用的匹配模式,好比忽略大小寫、多行匹配等,這部份內容將在Pattern類的工廠方法re.compile(pattern[, flags])中一塊兒介紹。編程
正則表達式是用來匹配處理字符串的 python 中使用正則表達式須要引入re模塊編程語言
import re # 第一步,要引入re模塊 a = re.findall("匹配規則", "這個字符串是否有匹配規則的字符") # 第二步,調用模塊函數 print(a) # 以列表形式返回匹配到的字符串
['匹配規則']
^元字符
[^a-z]反取
$元字符
*元字符
+元字符
?元字符(防止貪婪匹配)
{}元字符(範圍)
[]元字符(字符集)
[^]
\d+
\D
\s
\S
\w
\W
()元字符(分組)
|元字符(或)函數
1.一種是直接在函數裏書寫規則,推薦使用工具
import re a = re.findall("匹配規則", "這個字符串是否有匹配規則的字符") print(a)
['匹配規則']
2.另外一種是先將正則表達式的字符串形式編譯爲Pattern實例,而後使用Pattern實例處理文本並得到匹配結果(一個Match實例),最後使用Match實例得到信息,進行其餘的操做。code
import re # 將正則表達式編譯成Pattern對象 pattern = re.compile(r'hello') # 使用Pattern匹配文本,得到匹配結果,沒法匹配時將返回None match = pattern.match('hello world!') if match: # 使用Match得到分組信息 print(match.group())
hello
對象
這個方法是Pattern類的工廠方法,用於將字符串形式的正則表達式編譯爲Pattern對象。 第二個參數flag是匹配模式,取值可使用按位或運算符'|'表示同時生效,好比re.I | re.M。另外,你也能夠在regex字符串中指定模式,好比re.compile('pattern', re.I | re.M)與re.compile('(?im)pattern')是等價的。字符串
下表是全部的正則匹配模式:
修飾符|描述
-|:-:|-:
re.I|使匹配對大小寫不敏感
re.L|作本地化識別(locale-aware)匹配
re.M|多行匹配,影響 ^ 和 $
re.S|使 . 匹配包括換行在內的全部字符
re.U|根據Unicode字符集解析字符。這個標誌影響 \w, \W, \b, \B.
re.X|該標誌經過給予你更靈活的格式以便你將正則表達式寫得更易於理解。
* 在Python的正則表達式中,有一個參數爲re.S。它表示 「.」 的做用擴展到整個字符串,包括「\n」。看以下代碼:
import re a = '''asdfhellopass: worldaf ''' b = re.findall('hello(.*?)world', a) c = re.findall('hello(.*?)world', a, re.S) print('b is ', b) print('c is ', c)
b is [] c is ['pass:\n ']
正則表達式中,「.」的做用是匹配除「\n」之外的任何字符,也就是說,它是在一行中進行匹配。這裏的「行」是以「\n」進行區分的。a字符串有每行的末尾有一個「\n」,不過它不可見。
若是不使用re.S參數,則只在每一行內進行匹配,若是一行沒有,就換下一行從新開始,不會跨行。而使用re.S參數之後,正則表達式會將這個字符串做爲一個總體,將「\n」當作一個普通的字符加入到這個字符串中,在總體中進行匹配。
* 不區分大小寫
res = re.findall(r"A", "abc", re.I) print(res)
['a']
* 將全部行的尾字母輸出(python3+已經無效)
s = '12 34/n56 78/n90' re.findall(r'^/d+', s, re.M) # 匹配位於行首的數字 # ['12', '56', '90'] re.findall(r'/A/d+', s, re.M) # 匹配位於字符串開頭的數字 # ['12'] re.findall(r'/d+$', s, re.M) # 匹配位於行尾的數字 # ['34', '78', '90'] re.findall(r'/d+/Z', s, re.M) # 匹配位於字符串尾的數字 # ['90']
# 要求結果:['12', '23', '34'] l = ['1 2 ', '2 3', ' 3 4'] import re print(eval(re.sub(r'\s*', '', str(l))))
['12', '23', '34']
match,從頭匹配一個符合規則的字符串,從起始位置開始匹配,匹配成功返回一個對象,未匹配成功返回None
match(pattern, string, flags=0)
* pattern: 正則模型
* string : 要匹配的字符串
* falgs : 匹配模式
注意:match()函數 與 search()函數基本是同樣的功能,不同的就是match()匹配字符串開始位置的一個符合規則的字符串,search()是在字符串全局匹配第一個合規則的字符串
import re # 無分組 origin = "hello egon bcd egon lge egon acd 19" r = re.match("h\w+", origin) # match,從起始位置開始匹配,匹配成功返回一個對象,未匹配成功返回None print(r.group()) # 獲取匹配到的全部結果,無論有沒有分組將匹配到的所有拿出來 print(r.groups()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果 print(r.groupdict()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果
hello () {}
# 有分組 # 爲什麼要有分組?提取匹配成功的指定內容(先匹配成功所有正則,再匹配成功的局部內容提取出來) r = re.match("h(\w+)", origin) # match,從起始位置開始匹配,匹配成功返回一個對象,未匹配成功返回None print(r.group()) # 獲取匹配到的全部結果,無論有沒有分組將匹配到的所有拿出來 print(r.groups()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果 print(r.groupdict()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果
hello ('ello',) {}
# 有兩個分組定義了key # 爲什麼要有分組?提取匹配成功的指定內容(先匹配成功所有正則,再匹配成功的局部內容提取出來) # ?P<>定義組裏匹配內容的key(鍵),<>裏面寫key名稱,值就是匹配到的內容 r = re.match("(?P<n1>h)(?P<n2>\w+)", origin) print(r.group()) # 獲取匹配到的全部結果,無論有沒有分組將匹配到的所有拿出來 print(r.groups()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果 print(r.groupdict()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果
hello ('h', 'ello') {'n1': 'h', 'n2': 'ello'}