正則表達式 正則表達式為高級的文本模式匹配、抽取、與/或文本形式的搜索和替換功能提供了基礎。簡單的說,正則表達式是一些由字元和特殊符號組成的字元串,他們描述了模式的重覆或者表述多個字元,於是正則表達式能按照某種模式匹配一系列有相似特征的字元串。換句話說,他們能夠匹配多個字元串,一種只能匹配一個字元串 ...
正則表達式
正則表達式為高級的文本模式匹配、抽取、與/或文本形式的搜索和替換功能提供了基礎。簡單的說,正則表達式是一些由字元和特殊符號組成的字元串,他們描述了模式的重覆或者表述多個字元,於是正則表達式能按照某種模式匹配一系列有相似特征的字元串。換句話說,他們能夠匹配多個字元串,一種只能匹配一個字元串的正則表達式模式是很乏味並且毫無作用的。
主要分為兩部分:
1.正則表達式
2.python中的re模塊
所有關於正則表達式的操作都使用 python 標準庫中的 re 模塊。
我們的第一個正則表達式
1 import re 2 3 pattern = re.compile(r'Python')#進行預編譯 4 m = re.search(pattern,'Hello Python') 5 6 print(m.group())
>>>Python
1 import re
2
3 m = re.search(r'Python','Hello Python')
4
5 print(m.group())
#沒有預編譯,結果也是相同的
>>>Python
1.pattern = re.compile(r'Python')
將正則表達式進行預編譯,也可以不編譯直接進行匹配,但是在代碼執行過程中,解釋器都會將正則表達式模式編譯成正則表達式對象,而且正則表達式在執行過程中將進行多次比較操作,因此強烈建議使用預編譯。
2.r'Python'
一個形式最簡單的正則表達式,匹配字元串中的Python。
python中字元串前面加 r 表示原生字元串
與大多數編程語言相同,正則表達式里使用"\"作為轉義字元,這就可能造成反斜杠困擾。假如你需要匹配文本中的字元"\",那麼使用編程語言表示的正則表達式里將需要4個反斜杠"\\\\":前兩個和後兩個分別用於在編程語言里轉義成反斜杠,轉換成兩個反斜杠後再在正則表達式里轉義成一個反斜杠。Python里的原生字元串很好地解決了這個問題,這個例子中的正則表達式可以使用r"\\"表示。同樣,匹配一個數字的"\\d"可以寫成r"\d"。有了原生字元串,你再也不用擔心是不是漏寫了反斜杠,寫出來的表達式也更直觀。原生字元串
正則表達式的表達方式還有很多,一會兒會做說明,更詳細的還請查閱相關文檔。
3.re.search(r'Python','Hello Python')
調用 python 中 re 模塊的 search() 方法,第一個參數是正則表達式,第二個參數是要進行匹配的字元串,返回一個匹配對象。
re 模塊中還有很多方法,下麵也會做介紹。
4.m.group()
m就是匹配對象,所以如果直接print(m),會輸出一個對象,並不能得到我們想看到的匹配結果。
匹配對象有兩個主要的方法:group()和groups(),我們用這兩個方法來得到我們想要的結果。具體用法後面會詳細講解。
下麵進入到正式的正則表達式學習中
接下來會將我們上面第一個正則表達式中的知識點進行詳細講解,如果在接下來的學習中感到困惑,試著將相關內容替換到上面的代碼中理解。
一、正則表達式
1.普通字元描述
. | 匹配除 “\n” 之外的任何單個字元。要匹配包括 ‘\n’ 在內的任何字元,請使用象 ‘[.\n]‘ 的模式。 |
x|y | 匹配 x 或 y。例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 則匹配 “zood” 或 “food”。 |
[xyz] | 字元集合。匹配所包含的任意一個字元。例如, ‘[abc]‘ 可以匹配 “plain” 中的 ‘a’。 |
[^xyz] | 負值字元集合。匹配未包含的任意字元。例如, ‘[^abc]‘ 可以匹配 “plain” 中的’p','l','i','n'。 |
[a-z] | 字元範圍。匹配指定範圍內的任意字元。例如,’[a-z]‘ 可以匹配 ‘a’ 到 ‘z’ 範圍內的任意小寫字母字元。 |
[^a-z] | 負值字元範圍。匹配任何不在指定範圍內的任意字元。例如,’[^a-z]‘ 可以匹配任何不在 ‘a’ 到 ‘z’ 範圍內的任意字元。 |
\d | 匹配一個數字字元。等價於 [0-9]。 |
\D | 匹配一個非數字字元。等價於 [^0-9]。 |
\w | 匹配包括下劃線的任何單詞字元。等價於’[A-Za-z0-9_]‘。 |
\W |
匹配任何非單詞字元。等價於 ‘[^A-Za-z0-9_]‘。 |
2.特殊字元描述
$ | 匹配輸入字元串的結尾位置。如果設置了 RegExp 對象的 Multiline 屬性,則 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字元本身,請使用 \$。 |
( ) | 標記一個子表達式的開始和結束位置。子表達式可以獲取供以後使用。要匹配這些字元,請使用 \( 和 \)。 |
* | 匹配前面的子表達式零次或多次。要匹配 * 字元,請使用 \*。 |
+ | 匹配前面的子表達式一次或多次。要匹配 + 字元,請使用 +。 |
. | 匹配除換行符 \n之外的任何單字元。要匹配 .,請使用 \。 |
[ | 標記一個中括弧表達式的開始。要匹配 [,請使用 \[。 |
? | 匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字元,請使用 \?。 |
\ | 將下一個字元標記為或特殊字元、或原義字元、或後向引用、或八進位轉義符。例如, 'n' 匹配字元 'n'。'\n' 匹配換行符。序列 '\' 匹配 "\",而 '\(' 則匹配 "("。 |
^ | 匹配輸入字元串的開始位置,除非在方括弧表達式中使用,此時它表示不接受該字元集合。要匹配 ^ 字元本身,請使用\^。 |
{ | 標記限定符表達式的開始。要匹配 {,請使用 \{。 |
| | 指明兩項之間的一個選擇。要匹配 |,請使用 \|。 |
3.非列印字元
\f | 匹配一個換頁符。等價於 \x0c 和 \cL。 |
\n | 匹配一個換行符。等價於 x0a 和 cJ。 |
\r | 匹配一個回車符。等價於 x0d 和 cM。 |
\s | 匹配任何空白字元,包括空格、製表符、換頁符等等。等價於 [?\f\n\r\t\v]。 |
\S | 匹配任何非空白字元。等價於 [^?\f\n\r\t\v]。 |
\t | 匹配一個製表符。等價於 \x09 和 \cI。 |
\v | 匹配一個垂直製表符。等價於 \x0b 和 \cK。 |
4.限定符
* | 匹配前面的子表達式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。 * 等價於{0,}。 |
+ | 匹配前面的子表達式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等價於 {1,}。 |
? | 匹配前面的子表達式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等價於 {0,1}。 |
{n} | n 是一個非負整數。匹配確定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的兩個 o。 |
{n,} | n 是一個非負整數。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等價於 ‘o+’。’o{0,}’ 則等價於 ‘o*’。 |
{n,m} | m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。劉, “o{1,3}” 將匹配 “fooooood” 中的前三個 o。’o{0,1}’ 等價於 ‘o?’。請註意在逗號和兩個數之間不能有空格。 |
看了這麼多,我們來上一些實例看看:
m = re.search(r'(p|t)h','the') print(m.group()) #>>>th m = re.search(r'[abcde]','the')#匹配字元集中任意字元 print(m.group()) #>>>e m = re.search(r'..','the')# . 匹配任意字元(不包括\n) print(m.group()) #>>>th m = re.search(r'^ind(e|a)','inda inde')#匹配字元串起始部分 print(m.group()) #>>>inda m = re.search(r'ind(e|a)$','inda inde')#匹配字元串終止部分 print(m.group()) #>>>inde m = re.search(r'inde*','indeeeee')#匹配0次或多次前面出現的正則表達式 print(m.group()) #>>>indeeeee m = re.search(r'inde{3}','indeeeee')#匹配n次前面出現的正則表達式 print(m.group()) #>>>indeee m = re.search(r'inde*?','indeeeee')# 非貪婪匹配 print(m.group()) #>>>ind m = re.search(r'inde+?','indeeeee')# 非貪婪匹配 print(m.group()) #>>>inde m = re.search(r'i(nd)e*','indeeeee')# ()用於分組,配合group()方法使用 print(m.group(0),m.group(1)) #>>>indeeeee nd示例
二、正則表達式和python語言
1.match()方法
從字元串的起始部分對模式進行匹配,如果匹配成功,就返回一個匹配對象,如果匹配失敗,就返回None
2.search()方法
在字元串中搜索出模式第一次出現的匹配情況,如果成功就返回匹配對象,失敗返回None
3.findall()和finditer()查找每一次出現的位置
查找模式在字元串中出現的所有位置,與search()和match()不同的是findall()總是返回一個列表,匹配失敗返回一個空列表,匹配成功,列表將包含所有成功的匹配部分。
finditer()與findall()的區別在於返回的是一個迭代器還是一個列表。更節省記憶體。
4.sub()和subn()搜索與替換
兩者幾乎一樣,都是將某字元串中所有匹配正則表達式的部分進行某種形式的替換。
不同的是返回的值,sub()返回替換後的字元串,subn()返回替換後的字元串和表示替換總數的數字,一起作為一個擁有兩個元素的元組返回
5.split()分割字元串
re.split()與str.split()的工作方式相同,可以通過為參數max設定一個值來指定最大分割數
m = re.match(r'foo','food on the table') if m is not None: print(m.group()) #>>>foo m = re.search(r'foo','seafood') if m is not None: print(m.group()) #>>>foo m = re.findall(r'th\w+','This and that.') print(m) #>>>['that'] m = re.findall(r'th\w+','This and that.',re.I)#不區分大小寫 print(m) #>>>['This','that'] m = re.finditer(r'th\w+','This and that.',re.I) for i in m: print(i.group()) #>>>This #>>>that m = re.sub(r'[ae]','X','abcdef') print(m) #>>>XbcdXf m = re.subn(r'[ae]','X','abcdef') print(m) #>>>('XbcdXf', 2) m = re.split(':','str1:str2:str3') print(m) #>>>['str1', 'str2', 'str3']示例
6.group()和groups()方法
匹配成功後返回的匹配對象擁有兩個方法,group()和groups()。
group()要麼返回整個匹配對象,要麼根據要求返回特定子組。groups()則返回一個包含唯一或者全部子組的元組。如果沒有子組的要求,group()任然返回整個匹配,groups()則返回一個空元組。
m = re.match(r'(\w\w\w)-(\d\d\d)','abc-123') print(m.group()) #>>>abc-123 print(m.group(1)) #>>>abc print(m.group(2)) #>>>123 print(m.groups()) #>>>('abc', '123')示例
7.常用正則表達式
- 手機:/^0?1[3|4|5|8][0-9]\d{8}$/
- 固話:/^0[\d]{2,3}-[\d]{7,8}$/
- 電子郵箱:/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/
/^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/ - 用戶名:/^[a-z0-9_-]{3,16}$/
- 密碼:/^[a-z0-9_-]{6,18}$/
- URL:/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/