爬蟲筆記(六)——如何寫正則表示式詳解
什麼是正則表示式?
正則表示式(Regular Expression)是一種文字模式,在編寫處理字串的程式或網頁時,經常會有查詢符合某些規則的字串的需求。正則表示式就是用於描述這些規則的工具,換句話說,正則表示式就是記錄文字規則的程式碼。我們將分別從原子、元子符、模式修正符、貪婪模式與懶惰模式等方面進行介紹,程式碼引進re模組。
這篇部落格主要講如何寫正則表示式,下篇再介紹關於正則表示式的函式運用。
一、原子
原子是正則表示式中最基本的組成單位,每個正則表示式至少要包含一個原子,常見原子主要有以下幾類:
- 普通子符作為原子
- 非列印字元作為原子
- 通用字元作為原子
- 原子表
普通字元
import re
string = "wanglongxuepython"
pattern = "python"
result = re.search(pattern,string)
print (result)
#<_sre.SRE_Match object; span=(11, 17), match='python'>
非列印字元就是指在字串中起格式控制的符號,常見有換行符\n和製表符\t,其分別用來匹配換行和製表。
import re
string = '''wanglong
xuepython'''
pattern = "\n"
result = re.search(pattern,string)
print (result)
#<_sre.SRE_Match object; span=(8, 9), match='\n'>
如果string沒有包含換行,就會返回None。
import re string = "wanglongxuepython" pattern = "\n" result = re.search(pattern,string) print (result) #None
通用字元就是可以用一個原子匹配一類字元,常見的通用字元有以下幾個:
- \w 可以匹配任意一個大小寫字母、數字或下劃線的字元
- \W 可以匹配任意一個除大小寫字母、數字和下劃線以外的字元
- \s 可以匹配任意一個空白字元
- \S 可以匹配任意一個除空白字元以外的字元
- \d 可以匹配任意一個十進位制數
- \D 可以匹配任意一個除十進位制數以外的字元
比如我們用"\d\dxue\w"去匹配一個string"wanglong1314xuepython",就可以得到“14xuep"。
import re
string = "wanglong1314xuepython"
pattern = "\d\dxue\w"
result = re.search(pattern,string)
print (result)
#<_sre.SRE_Match object; span=(10, 16), match='14xuep'>
原子表就是定義一組地位平等的原子,然後匹配時會在原子表中取任意一個原子,用[ ]表示,比如[love]。還有一種是匹配時會取除原子表內原子以外任意一個,這種用[ ^]表示,比如[^love]。[a-z]表示是a到z。
import re
string = "wanglong1314xuepython"
pattern = "[love]ong13"
result = re.search(pattern,string)
print (result)
#<_sre.SRE_Match object; span=(4, 10), match='long13'>
二、元字元
所謂的元字元就是在正則表示式中具有特殊含義的字元,比如重複前面N次字元等。具體來說元字元分為任意匹配元字元、邊界限制元字元、限定符、模式選擇符、模式單元等。
任意匹配元字元用著'.'表示,他可以匹配除換行符以外的任意一個字元。
import re
string = "wanglong1314xuepython"
pattern = "...long...."
result = re.search(pattern,string)
print (result)
#<_sre.SRE_Match object; span=(1, 12), match='anglong1314'>
邊界限制元字元,可以使用"^"匹配字串的開始,使用"$"匹配字串的結束。
import re
string = "wanglong1314xuepython"
pattern1 = "^wang"
pattern2 = "^long"
pattern3 = "thon$"
pattern4 = "pyth$"
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
result3 = re.search(pattern3,string)
result4 = re.search(pattern4,string)
print (result1)
print (result2)
print (result3)
print (result4)
#<_sre.SRE_Match object; span=(0, 4), match='wang'>
#None
#<_sre.SRE_Match object; span=(17, 21), match='thon'>
#None
限定符也是元字元的一種,常見限定符有下面幾個:
- * 匹配0次、1次或多次前面的原子
- ? 匹配0次或1次前面的原子
- + 匹配1次或多次前面的原子
- {n} 前面的原子恰好出現n次
- {n,} 前面的原子至少出現n次
- {n,m} 前面的原子至少出現n次,至多出現m次
import re
string = "aabbbcde"
pattern1 = "a.*c"
pattern2 = "b?c"
pattern3 = "b+c"
pattern4 = "b{2}c"
pattern5 = "b{2,}c"
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
result3 = re.search(pattern3,string)
result4 = re.search(pattern4,string)
result5 = re.search(pattern5,string)
print (result1)
print (result2)
print (result3)
print (result4)
print (result5)
#<_sre.SRE_Match object; span=(0, 6), match='aabbbc'>
#<_sre.SRE_Match object; span=(4, 6), match='bc'>
#<_sre.SRE_Match object; span=(2, 6), match='bbbc'>
#<_sre.SRE_Match object; span=(3, 6), match='bbc'>
#<_sre.SRE_Match object; span=(2, 6), match='bbbc'>
模式選擇符用著‘|’表示,比如' A|B ',它可以任意選擇一種模式去匹配,即A模式和B模式,哪種模式更快匹配到則取哪種模式。
import re
string = "aabbbcde"
pattern1 = "ac|cd"
pattern2 = "cd|aa"
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
print (result1)
print (result2)
#<_sre.SRE_Match object; span=(5, 7), match='cd'>
#<_sre.SRE_Match object; span=(0, 2), match='aa'>
模式單元符用()表示,他可以將幾個單元符變成一個大單元。
import re
string = "aabbbbcde"
pattern1 = "(bb){2}cd"
pattern2 = "bb{2}cd"
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
print (result1)
print (result2)
#<_sre.SRE_Match object; span=(2, 8), match='bbbbcd'>
#<_sre.SRE_Match object; span=(3, 8), match='bbbcd'>
三、模式修正
所謂的模式修正就是在不改變正則表示式的情況下,通過模式修正改變正則表示式的含義,從而實現一些匹配結果調整等功能。常見的一些模式修正符有以下幾點:
- I 匹配時忽略大小寫
- M 多行匹配
- L 做本地識別匹配
- U 根據Unicode字元及解析字元
- S 讓.可以匹配換行符,即.可以匹配任意字元
import re
string = "aabbbbcde"
pattern1 = "bbBB"
result1 = re.search(pattern1,string)
result2 = re.search(pattern1,string,re.I)
print (result1)
print (result2)
#None
#<_sre.SRE_Match object; span=(2, 6), match='bbbb'>
四、貪婪模式與懶惰模式
貪婪模式的核心就是儘可能地多的匹配,懶惰模式的核心就是儘可能地少匹配。
import re
string = "wanglongphp223python_py"
pattern1 = "p.*y" #貪婪模式
pattern2 = "p.*?y" #懶惰模式
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
print (result1)
print (result2)
#<_sre.SRE_Match object; span=(8, 23), match='php223python_py'>
#<_sre.SRE_Match object; span=(8, 16), match='php223py'>