Python | 正則表示式的常見用法
正則表示式的常見用法分為兩塊內容,第一部分是一般具有正則的高階語言都支援的功能,第二部分講解Python所獨特具備的正則特性。
Part 1
正則表示式是由普通字元(例如字元a到z)以及特殊字元(稱為“元字元”)組成的文字模式。模式用於在搜尋文字時要匹配一個或多個字串。
(1).常見的元字元如下:
. 匹配除換行符以外的任意字元
\b 匹配單詞的開始和結束
\d 匹配數字
\w 匹配字母,數字,下劃線和漢字
\s 匹配任意空白符,包括空格,製表符(Tab),換行符,中文全形空格等
^ 匹配字串的開始
$ 匹配字串的結束
Examples:
1.匹配所有以s開頭的單詞 \bs\w*\b
2.匹配以s開頭後跟數字的字串(比如:s100) ^s\d*$
3.匹配網址(比如:www.google.com) www\.google\.com
(2).重複:
* 重複零次或更多次
+ 重複一次或更多次
? 重複零次或一次
{n} 重複n次
{n,} 重複n次或者更多次
{n,m} 重複n到m次
Examples:
1.匹配hello後面跟1個或更多數字 hello\d+
2.匹配5到12個數字的字串 ^\d{5,12}$
3.匹配we後面跟0個或者1個數字 we\d?
(3).字元集合:
[...], 利用自定義的字元集合,可以匹配幾個字元中的單個字元,以及字元範圍內的單個字元。
Examples:
1.匹配a,b,c,d,e中的單個字元 [abcde]
2.匹配0到8裡的數字 [0-8]
3.匹配所有的字母和數字 [0-9a-zA-Z]
(4).分支條件
正則表示式裡的分支條件指的是有幾種匹配規則,如果滿足其中任意一種規則都應該當成匹配,具體方法是用“|”把不同的規則分隔開。
Examples:
1.匹配電話號碼,一種是3位區號,8位本地號,比如:010-11223344;另一種是4位區號,7位本地號,比如:0321-1234567 0\d{2}-\d{8}|0\d{3}-\d{7}
2.匹配IP地址 ((25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.){3}((25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d))
(5).反義
有時候需要查詢除某一類字元集合以外的字元,這時就需要使用反義。
常用的反義:
\W 匹配任意不是字母,數字,下劃線,漢字的字元
\S 匹配任意不是空白符的字元
\D 匹配任意非數字的字元
\B 匹配不是單詞開頭或結束的位置
[^a] 匹配除了a以外的任意字元
[^abcde]匹配除了a,b,c,d,e以外的任意字元
[^(123|abc)] 匹配除了1,2,3 或者a,b,c這幾個字元以外的任意字元
(6).後向引用
...[比較繁瑣,故先省略]
(7).零寬斷言
...
(8).貪婪與懶惰
當正則表示式中包含能接受重複的限定符時,通常的行為是匹配儘可能多的字元,這就是貪婪模式。
以表示式a\w+b為例,如果搜尋a12b34b,最後會匹配a12b34b,而不是a12b。如果想匹配a12b,應使用“?”來開啟懶惰模式。
*? 重複任意次,但儘可能少重複
+? 重複1次或更多次,但儘可能少重複
?? 重複0次或1次,但僅可能少重複
{n,m} 重複n到m次,但儘可能少重複
{n,}? 重複n次以上,但儘可能少重複
(9).處理選項
...
Part 2
Python與正則
對不同的語言,對正則表示式的語法絕大部分都是支援的,但是還是有略微不同,每種語言都有一些獨特的匹配規則。
Python的匹配規則:
\A 僅匹配字串開頭
\Z 僅匹配字串末尾
(?P<name>) 分組,除了原有編號外再指定一個額外的別名
(?P=name) 引用別名為<name>的分組匹配到的字串
Python 通過re模組提供對正則表示式的支援
使用re的一般步驟是:
(1).先將正則表示式的字串形式編譯成Pattern例項;
(2).然後使用Pattern例項處理文字並獲得匹配結果Match例項;
(3).最後使用Match例項獲得資訊。
1.re.compile(string, [flags]) #它將一個正則表示式轉化為Pattern匹配物件
Example: pattern = re.compile(r'\d+')
2.re.match(pattern, string, [flags]) <等價於 pattern.match(string, [flags])>#該函式是從輸入引數string(匹配的字串)的開頭開始,嘗試匹配pattern,一直向後匹配,如果遇到無法匹配的字元或者已經到達string的末尾,立即返回None,反之,獲得匹配的結果。
Example:
# 1.將正則表示式編譯成pattern物件
pattern = re.compile(r'\d+')
# 2.使用re.match匹配文字,獲得匹配結果,無法匹配時將返回None
result1 = re.match(pattern, '192abc')
if result1:
print(result1.group())
else:
print('匹配失敗1')
result2 = re.match(pattern, 'abc192')
if result2:
print(result2.group())
else:
print('匹配失敗2')
Result:
192
匹配失敗2
3.re.search(pattern, string, [flags]) <等價於 pattern.search(string, [flags])> #search方法和match方法很類似,只是search()會掃描整個string查詢匹配,而不是從string的開始位置進行匹配
Example:
# search方法的返回物件在方法和屬性上和match是一致的
import re
# 將正則表示式編譯成pattern物件
pattern = re.compile(r'\d+')
result1 = re.search(pattern, 'abc192edf333')
if result1:
print(result1.group())
else:
print('匹配失敗1')
Result:
192
4.re.split(pattern, string, [flags]) # split 能夠匹配的子串將string分割後返回列表
Example:
import re
pattern = re.compile(r'\d+')
print(re.split(pattern, 'a1b2c3d4'))
Result:
['a', 'b', 'c', 'd', '']
5.re.findall(pattern, string, [flags]) # findall 搜尋整個string,以列表的形式返回能匹配的全部子串
Example:
import re
pattern = re.compile(r'\d+')
print(re.findall(pattern, 'a1b2c3d4'))
Result:
['1', '2', '3', '4']
6.re.finditer(pattern, string, [flags]) # finditer 搜尋整個string,以迭代器形式返回能匹配的全部Match物件
Example:
import re
pattern = re.compile(r'\d+')
matchiter = re.finditer(pattern, 'a1b2c3d4')
for match in matchiter:
print(match.group())
Result:
1
2
3
4
7.re.sub(pattern, repl, string [,count])
Example:
import re
p = re.compile(r'(?P<word1>\w+) (?P<word2>\w+)') #使用名稱引用
s = 'I say, hello, world!'
print(re.sub(p, '111', 'asd f?fdf ss!fdas [email protected]'))
Result:
[email protected]
8.re.subn(pattern, repl, string [,count])
#用法和上者類似,只是返回( sub(repl, string[, count]), 替換次數 )