【正則表示式】Python3中的正則表示式
介紹
正則表示式(Regular Expression)是一種文字模式,包括普通字元(例如,a 到 z 之間的字母)和特殊字元(稱為"元字元")。
正則表示式使用單個字串來描述、匹配一系列匹配某個句法規則的字串(一個特殊的字元序列),來幫助我們方便的檢查一個字串是否與某種模式匹配。
常用的正則表示式
字元 | 描述 |
---|---|
\ | 將下一個字元標記為一個特殊字元、或一個原義字元、或一個向後引用、或一個八進位制轉義符。例如,“n”匹配字元“n”。“\n”匹配一個換行符。序列“\\”匹配“\”而“\(”則匹配“(”。 |
^ | 匹配輸入字串的開始位置。如果設定了RegExp物件的Multiline屬性,^也匹配“\n”或“\r”之後的位置。 |
$ | 匹配輸入字串的結束位置。如果設定了RegExp物件的Multiline屬性,$也匹配“\n”或“\r”之前的位置。 |
* | 匹配前面的子表示式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等價於{0,}。 |
+ | 匹配前面的子表示式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等價於{1,}。 |
? | 匹配前面的子表示式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等價於{0,1}。當該字元緊跟在任何一個其他限制符(*,+,?,{n},{n,},{n,m})後面時,匹配模式是非貪婪的。非貪婪模式儘可能少的匹配所搜尋的字串,而預設的貪婪模式則儘可能多的匹配所搜尋的字串。例如,對於字串“oooo”,“o+?”將匹配單個“o”,而“o+”將匹配所有“o”。 |
{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?”。請注意在逗號和兩個數之間不能有空格。 |
. | 匹配除“\n”之外的任何單個字元。要匹配包括“\n”在內的任何字元,請使用像“(.|\n)”的模式。 |
(pattern) | 匹配pattern並獲取這一匹配,子表示式可以供以後使用。所獲取的匹配可以從產生的 Matches 集合得到。要匹配圓括號字元,請使用“\(”或“\)”。 |
x|y | 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”則匹配“zood”或“food”。 |
[xyz] | 字元集合。匹配所包含的任意一個字元。例如,“[abc]”可以匹配“plain”中的“a”。 |
[^xyz] | 負值字元集合。匹配未包含的任意字元。例如,“[^abc]”可以匹配“plain”中的“p”。 |
[a-z] | 字元範圍。匹配指定範圍內的任意字元。例如,“[a-z]”可以匹配“a”到“z”範圍內的任意小寫字母字元。 |
[^a-z] | 負值字元範圍。匹配任何不在指定範圍內的任意字元。例如,“[^a-z]”可以匹配任何不在“a”到“z”範圍內的任意字元。 |
\b | 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。 |
\B | 匹配非單詞邊界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 |
\d | 匹配一個數字字元。等價於[0-9]。 |
\D | 匹配一個非數字字元。等價於[^0-9]。 |
\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。 |
\w | 匹配包括下劃線的任何單詞字元。等價於“[A-Za-z0-9_]”。 |
\W | 匹配任何非單詞字元。等價於“[^A-Za-z0-9_]”。 |
\num | 匹配num,其中num是一個正整數。對所獲取的匹配的引用。例如,“(.)\1”匹配兩個連續的相同字元。 |
Python3中的re模組
Python中的re 模組擁有全部的正則表示式功能。
Python中常用的正則表示式處理函式
1. re.match函式
re.match 嘗試從字串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none。 語法:
re.match(pattern, string, flags=0)
引數說明:
引數 | 描述 |
---|---|
pattern | 匹配的正則表示式 |
string | 要匹配的字串。 |
flags | 標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。 |
標誌位:
修飾符 | 描述 |
---|---|
re.I | 使匹配對大小寫不敏感 |
re.L | 做本地化識別(locale-aware)匹配 |
re.M | 多行匹配,影響 ^ 和 $ |
re.S | 使 . 匹配包括換行在內的所有字元 |
re.U | 根據Unicode字符集解析字元。這個標誌影響 \w, \W, \b, \B. |
re.X | 該標誌通過給予你更靈活的格式以便你將正則表示式寫得更易於理解。 |
例項:
import re
print(re.match('dog', 'dog cat dog cat')) # 在起始位置匹配
print(re.match('cat', 'dog cat dog cat')) # 不在起始位置匹配
執行結果:
匹配成功re.match方法返回一個匹配的物件,否則返回None。
當匹配成功時返回一個 Match 物件,可以通過以下方法獲取相應的值:
- group([group1, …]) 方法用於獲得一個或多個分組匹配的字串,當要獲得整個匹配的子串時,可直接使用 group() 或 group(0);
- start([group]) 方法用於獲取分組匹配的子串在整個字串中的起始位置(子串第一個字元的索引),引數預設值為 0;
- end([group]) 方法用於獲取分組匹配的子串在整個字串中的結束位置(子串最後一個字元的索引+1),引數預設值為 0;
- span([group]) 方法返回 (start(group), end(group))。
import re
line = "Cats are smarter than dogs"
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I) # 使用(parttern),獲取後可在Match物件中得到,通過group
if matchObj:
print("匹配結果 : ", matchObj.group())
print("第一個匹配項 : ", matchObj.group(1))
print("第一個匹配項開始下標 : ", matchObj.start(1))
print("第二個匹配項 : ", matchObj.group(2))
print("第二個匹配項結束下標 : ", matchObj.end(2))
print("第一個匹配項開始,結束下標範圍 : ", matchObj.span(1))
else:
print("No match!!")
執行結果:
2. re.search方法
re.search 掃描整個字串並返回第一個成功的匹配。
語法:
re.search(pattern, string, flags=0)
引數說明同上
匹配成功re.search方法返回一個匹配的物件,否則返回None。
同樣可以使用group(num) 或 groups() 匹配物件函式來獲取匹配表示式。
例項:
import re
print(re.search('dog', 'dog cat dog cat')) # 在起始位置匹配
print(re.search('cat', 'dog cat dog cat')) # 不在起始位置匹配
執行結果:
import re
line = "Cats are smarter than dogs"
searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I) # 使用(parttern),獲取後可在Match物件中得到,通過group
if searchObj:
print("匹配結果 : ", searchObj.group())
print("第一個匹配項 : ", searchObj.group(1))
print("第一個匹配項開始下標 : ", searchObj.start(1))
print("第二個匹配項 : ", searchObj.group(2))
print("第二個匹配項結束下標 : ", searchObj.end(2))
print("第一個匹配項開始,結束下標範圍 : ", searchObj.span(1))
else:
print("No match!!")
執行結果:
3. re.match與re.search的區別
re.match只匹配字串的開始,如果字串開始不符合正則表示式,則匹配失敗,函式返回None;而re.search匹配整個字串,直到找到一個匹配。
import re
line = "Cats are smarter than dogs";
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
print ("match --> matchObj.group() : ", matchObj.group())
else:
print ("No match!!")
matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
print ("search --> matchObj.group() : ", matchObj.group())
else:
print ("No match!!")
執行結果:
4. 檢索和替換
Python 的re模組提供了re.sub用於替換字串中的匹配項。
語法:
re.sub(pattern, repl, string, count=0)
引數說明:
- pattern : 正則中的模式字串。
- repl : 替換的字串,也可為一個函式。
- string : 要被查詢替換的原始字串。
- count : 模式匹配後替換的最大次數,預設 0 表示替換所有的匹配。
例項:
import re
phone = "2004-959-559 # 這是一個電話號碼"
# 刪除註釋
num = re.sub(r'#.*$', "", phone)
print ("電話號碼 : ", num)
# 移除非數字的內容
num = re.sub(r'\D', "", phone)
print ("電話號碼 : ", num)
執行結果:
repl 引數可以是一個函式
例項:
import re
# 將匹配的數字乘於 2
def double(matched):
value = int(matched.group('value'))
return str(value * 2)
s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))
執行結果:
5. compile 函式
compile 函式用於編譯正則表示式,生成一個正則表示式( Pattern )物件,供 match() 和 search() 這兩個函式使用。
語法:
re.compile(pattern[, flags])
引數說明:
- pattern : 一個字串形式的正則表示式
- flags 可選,表示匹配模式,比如忽略大小寫,多行模式等,具體引數為:
例項:
import re
pattern = re.compile(r'\d+') # 用於匹配至少一個數字
m = pattern.match('one12twothree34four') # 查詢頭部,沒有匹配
print(m)
m = pattern.match('one12twothree34four', 2, 10) # 從'e'的位置開始匹配,沒有匹配
print(m)
m = pattern.match('one12twothree34four', 3, 10) # 從'1'的位置開始匹配,正好匹配
print(m) # 返回一個 Match 物件
print(m.group(0)) # 可省略 0
print(m.start(0)) # 可省略 0
print(m.end(0)) # 可省略 0
print(m.span(0)) # 可省略 0
執行結果:
6. findall函式
在字串中找到正則表示式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。
注意: match 和 search 是匹配一次 findall 匹配所有。
語法:
findall(string[, pos[, endpos]])
引數說明:
- string 待匹配的字串。
- pos 可選引數,指定字串的起始位置,預設為 0。
- endpos 可選引數,指定字串的結束位置,預設為字串的長度。
例項:
import re
pattern = re.compile(r'\d+') # 查詢數字
result1 = pattern.findall('dasd 123 ddaer 456')
result2 = pattern.findall('dd88ab123goddle456', 0, 10)
print(result1)
print(result2)
執行結果:
7. re.finditer函式
和 findall 類似,在字串中找到正則表示式所匹配的所有子串,並把它們作為一個迭代器返回。
語法:
re.finditer(pattern, string, flags=0)
引數說明:同第一個
例項:
import re
it = re.finditer(r"\d+","12a32bc43jf3")
for match in it:
print (match.group() )
執行結果:
8. re.split函式
split 方法按照能夠匹配的子串將字串分割後返回列表。
語法:
re.split(pattern, string[, maxsplit=0, flags=0])
引數說明:
- maxsplit:分隔次數,maxsplit=1 分隔一次,預設為 0,不限制次數。
- 其他同第一個
例項:
import re
print(re.split('\W+', 'dog, dog, dog.'))
print(re.split('(\W+)', ' dog, dog, dog.'))
print(re.split('\W+', ' dog, dog, dog.', 1))
print(re.split('a*', 'hello world')) # 對於一個找不到匹配的字串而言,split 不會對其作出分割
執行結果:
正則表示式物件
re.RegexObject
re.compile() 返回 RegexObject 物件。
re.MatchObject
group() 返回被 RE 匹配的字串。
- start() 返回匹配開始的位置
- end() 返回匹配結束的位置
- span() 返回一個元組包含匹配 (開始,結束) 的位置