python3正則表示式疑點記錄
python正則表示式的以下幾個表示式比較疑惑,想清楚之後記錄如下:
1、pythopn正則常用的搜尋模組主要是re.findall()和re.search(),通常情況下有兩種使用方式。通過建立正則類:re.complie()來進行匹配,或者直接使用re.findall()和re.search()進行匹配。
2、兩種匹配方式其實都差不多,同一個欄位需要多次匹配則用re.compile()匹配,對統一字串多次處理可以使用第二種方法。
3、深坑!:使用search()返回第一個匹配到的目標的match類,使用findall()返回一個列表。此處有一個巨坑,就是在使用()進行分組的時候,findall()最後得到的結果是()分組裡面的結果,而不是匹配到的整個值(search不會),所以如果要匹配整個的話,使用(?:...)前面加問號和冒號才可以一起匹配。出現這個問題的原因是()分組會進入快取,直接寫入最後的列表裡。
準確的說是,不加?:返回括號內資料,加了返回整個的資料。匹配位置還是一樣的
4、介紹一些基本用法:
你們可以參考:http://www.runoob.com/regexp/regexp-tutorial.html,講得更好。
匹配多行表示式的時候,千萬不要忘記了換行符的存在,不然會匹配不到多行。re.S可以匹配多行,但是換行符是一個符號,跨行匹配的時候不要忘記換行符的匹配,可以用 . 來匹配換行符。
import urllib.request as request import urllib.parse as parse import re s = """<div class="animal"> <p class="name"> <a title="tiger"></a> </p> <p class="contents"> Two tigers two tigers run fast </p> </div> <div class="animal"> <p class="name"> <a title="rabbit"></a> </p> <p class="contents"> Small while rabbit white and white </p> </div>""" p1=re.compile('<div class="animal">.*? title="(\w+)".*?class="contents".*?\s([\w\b].*?)</p>.*?</div>',re.S) # print(re.findall(r"2000(?=(?:windows|Windows))", x)) r=p1.findall(s) print(r)
5、個人見解:
在findall裡面使用括號分組的時候,一定不要忘了?:。還有正向預匹配格式: aaa(?=...)匹配整個格式但是隻獲取前面的aaa
匹配一串字串的所有windows2000或Windows2000的2000:
x="Windows2000windows2000windows2000Windows2000"
print(re.findall(r"2000(?=(?:windows|Windows))", x))
>>>['2000', '2000', '2000']
其他的情況均如上程式碼所示。
另:附上預匹配的四種情況。用處很大希望自己能記住。。。。
(?:pattern) | 匹配 pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行儲存供以後使用。這在使用 "或" 字元 (|) 來組合一個模式的各個部分是很有用。例如, 'industr(?:y|ies) 就是一個比 'industry|industries' 更簡略的表示式。 |
(?=pattern) | 正向肯定預查(look ahead positive assert),在任何匹配pattern的字串開始處匹配查詢字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。預查不消耗字元,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜尋,而不是從包含預查的字元之後開始。 |
(?!pattern) | 正向否定預查(negative assert),在任何不匹配pattern的字串開始處匹配查詢字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。預查不消耗字元,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜尋,而不是從包含預查的字元之後開始。 |
(?<=pattern) | 反向(look behind)肯定預查,與正向肯定預查類似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows "能匹配"2000Windows "中的"Windows ",但不能匹配"3.1Windows "中的"Windows "。 |
(?<!pattern) | 反向否定預查,與正向否定預查類似,只是方向相反。例如"(?<!95|98|NT|2000)Windows "能匹配"3.1Windows "中的"Windows ",但不能匹配"2000Windows "中的"Windows "。 |
re模組
flags 引數的使用:輔助正則表示式,豐富匹配結果,使用為re.I或re.S等
I == IGNORECASE 匹配時忽略字母的大小寫
S == DOTALL 作用於元字元 . 使其可以匹配換行
M == MULTILINE 作用於^ $ 使其可以匹配每一行開頭結尾位置
X == VERBOSE 可以給正則添加註釋
類方法:
regex = compile(pattern,flags = 0),方法和re.的方法一樣。
功能 : 生成正則表示式物件
引數 : pattern 正則表示式,flags 功能標誌位,豐富正則表示式的匹配功能
返回值 : 返回正則表示式物件
compile物件屬性:
flags : 標誌位
pattern : 正則表示式
groups: 有多少子組
groupindex : 捕獲組形成組名和序列號的字典
組名為鍵,第幾組為值
regex.findall(string,pos,endpos)
功能 :從目標字串查詢正則匹配內容
引數 : string 目標字串
pos 匹配目標的起始位置
endpos 匹配目標的終止位置
返回值 : 返回匹配到的內容
如果正則有子組則只返回子組對應內容
re.findall(pattern,string,flags)
功能 :從目標字串查詢正則匹配內容
引數 : pattern 正則表示式,string 目標字串,flags 標誌位
返回值 : 返回匹配到的內容,如果正則有子組則只返回子組對應內容。返回的是一個列表
基本方法:
re.split(pattern,string,flags = 0)
功能:根據正則匹配內容切割字串
引數: pattern string flags
返回值: 返回列表,列表中為切割的內容
re.sub(pattern,replaceStr,string,max,flags) 只替換一次
功能: 替換正則匹配到的目標子串部分
引數: pattern
replaceStr : 要替換的內容
string
max 最多替換幾處 預設全部替換
flags
返回值 : 返回替換後的字串
re.subn(pattern,replaceStr,string,max,flags) 替換所有
功能: 替換正則匹配到的目標子串部分
引數: pattern
replaceStr : 要替換的內容
string
max 最多替換幾處 預設全部替換
flags
返回值 : 返回一個元組,為實際替換了幾處和替換後的字串
re.finditer(pattern,string,flags)
功能: 使用正則表示式匹配目標字串
引數: pattern string flags
返回值: 返回一個迭代物件,迭代到的內容是一個match物件
fullmatch(pattern,string,flags):功能: 完全匹配目標字串
match(pattern,string,flags):功能: 從開頭位置匹配目標字串
search(pattern,string,flags)
功能: 正則表示式匹配目標字串,只匹配第一處
引數: pattern,string,flags
返回值:返回匹配到的match物件
如果沒匹配成功返回None
match物件屬性
屬性變數
pos 匹配目標字串的開始位置
endpos 匹配目標字串的結束位置
re 正則表示式
string 目標字串
lastgroup 最後一組的組名
lastindex 最後一組是第幾組
屬性方法
span() 匹配內容的開始位置
start() 匹配內容的結束位置
end() 匹配內容的起止位置
group()
功能 : 獲取match物件對應的內容
引數 : 預設為0 表示獲取整個正則匹配的內容
如果為序列號或者子組名則為獲取某個子組匹配的對應內容
返回值:返回得到的子串
groupdict() 獲取捕獲組名作為鍵,對應內容作為值的字 典
groups() 獲取每個子組匹配內容