先詳細的整理一下Python中的正則運算式的相關內容,正則運算式在Python爬蟲中的作用就像是老師點名時用的花名冊一樣,是必不可少的神兵利器,

一、 正則運算式基礎
1.1.概念介紹
正則運算式是用于處理字串的強大工具,它并不是Python的一部分,
其他編程語言中也有正則運算式的概念,區別只在于不同的編程語言實作支持的語法數量不同,
它擁有自己獨特的語法以及一個獨立的處理引擎,在提供了正則運算式的語言里,正則運算式的語法都是一樣的,
下圖展示了使用正則運算式進行匹配的流程:
正則運算式的大致匹配程序是:
1.依次拿出運算式和文本中的字符比較,
2.如果每一個字符都能匹配,則匹配成功;一旦有匹配不成功的字符則匹配失敗,3.如果運算式中有量詞或邊界,這個程序會稍微有一些不同,
3.光理論是不夠的,這里順便送大家一套2020最新python入門到高級專案實戰視頻教程,可以去小編的Python交流.裙 :七衣衣九七七巴而五(數字的諧音)轉換下可以找到了,還可以跟老司機交流討教!
1.2. 數量詞的貪婪模式與非貪婪模式
正則運算式通常用于在文本中查找匹配的字串,
貪婪模式,總是嘗試匹配盡可能多的字符;
非貪婪模式則相反,總是嘗試匹配盡可能少的字符,
Python里數量詞默認是貪婪的,
例如:正則運算式"ab*"如果用于查找"abbbc",將找到"abbb",
而如果使用非貪婪的數量詞"ab*?",將找到"a",
1.3. 反斜杠的問題
與大多數編程語言相同,正則運算式里使用""作為轉義字符,這就可能造成反斜杠困擾,
假如你需要匹配文本中的字符"",那么使用編程語言表示的正則運算式里將需要4個反斜杠"\":
第一個和第三個用于在編程語言里將第二個和第四個轉義成反斜杠,
轉換成兩個反斜杠后再在正則運算式里轉義成一個反斜杠用來匹配反斜杠,
這樣顯然是非常麻煩的,
Python里的原生字串很好地解決了這個問題,這個例子中的正則運算式可以使用r""表示,
同樣,匹配一個數字的"d"可以寫成r"d",
有了原生字串,媽媽再也不用擔心我的反斜杠問題~
二、 介紹re模塊
2.1. Compile
Python通過re模塊提供對正則運算式的支持,
使用re的一般步驟是:
Step1:先將正則運算式的字串形式編譯為Pattern實體,
Step2:然后使用Pattern實體處理文本并獲得匹配結果(一個Match實體),
Step3:最后使用Match實體獲得資訊,進行其他的操作,
我們新建一個re01.py來試驗一下re的應用:
代碼如下:
# -*- coding: utf-8 -*-
#一個簡單的re實體,匹配字串中的hello字串
#匯入re模塊
import re
# 將正則運算式編譯成Pattern物件,注意hello前面的r的意思是“原生字串”
pattern = re.compile(r'hello')
# 使用Pattern匹配文本,獲得匹配結果,無法匹配時將回傳None
match1 = pattern.match('hello world!')
match2 = pattern.match('helloo world!')
match3 = pattern.match('helllo world!')
#如果match1匹配成功
if match1:
# 使用Match獲得分組資訊
print match1.group()
else:
print 'match1匹配失敗!'
#如果match2匹配成功
if match2:
# 使用Match獲得分組資訊
print match2.group()
else:
print 'match2匹配失敗!'
#如果match3匹配成功
if match3:
# 使用Match獲得分組資訊
print match3.group()
else:
print 'match3匹配失敗!'
可以看到控制臺輸出了匹配的三個結果:
下面來具體看看代碼中的關鍵方法,
★ re.compile(strPattern[, flag]):
這個方法是Pattern類的工廠方法,用于將字串形式的正則運算式編譯為Pattern物件,
第二個引數flag是匹配模式,取值可以使用按位或運算子'|'表示同時生效,比如re.I | re.M,
另外,你也可以在regex字串中指定模式,
比如re.compile('pattern', re.I | re.M)與re.compile('(?im)pattern')是等價的,
可選值有:
re.I(全拼:IGNORECASE): 忽略大小寫(括號內是完整寫法,下同)
re.M(全拼:MULTILINE): 多行模式,改變'^'和'$'的行為(參見上圖)
re.S(全拼:DOTALL): 點任意匹配模式,改變'.'的行為
re.L(全拼:LOCALE): 使預定字符類 w W B s S 取決于當前區域設定
re.U(全拼:UNICODE): 使預定字符類 w W B s S d D 取決于unicode定義的字符屬性
re.X(全拼:VERBOSE): 詳細模式,這個模式下正則運算式可以是多行,忽略空白字符,并可以加入注釋,
以下兩個正則運算式是等價的:
代碼如下:
# -*- coding: utf-8 -*-
#兩個等價的re匹配,匹配一個小數
import re
a = re.compile(r"""d + # the integral part
. # the decimal point
d * # some fractional digits""", re.X)
b = re.compile(r"d+.d*")
match11 = a.match('3.1415')
match12 = a.match('33')
match21 = b.match('3.1415')
match22 = b.match('33')
if match11:
# 使用Match獲得分組資訊
print match11.group()
else:
print u'match11不是小數'
if match12:
# 使用Match獲得分組資訊
print match12.group()
else:
print u'match12不是小數'
if match21:
# 使用Match獲得分組資訊
print match21.group()
else:
print u'match21不是小數'
if match22:
# 使用Match獲得分組資訊
print match22.group()
else:
print u'match22不是小數'
re提供了眾多模塊方法用于完成正則運算式的功能,
這些方法可以使用Pattern實體的相應方法替代,唯一的好處是少寫一行re.compile()代碼,
但同時也無法復用編譯后的Pattern物件,
這些方法將在Pattern類的實體方法部分一起介紹,
如一開始的hello實體可以簡寫為:
代碼如下:
# -*- coding: utf-8 -*- #一個簡單的re實體,匹配字串中的hello字串 import re m = re.match(r'hello', 'hello world!') print m.group()
2.2. Match
Match物件是一次匹配的結果,包含了很多關于此次匹配的資訊,可以使用Match提供的可讀屬性或方法來獲取這些資訊,
屬性:
string: 匹配時使用的文本,
re: 匹配時使用的Pattern物件,
pos: 文本中正則運算式開始搜索的索引,值與Pattern.match()和Pattern.seach()方法的同名引數相同,
endpos: 文本中正則運算式結束搜索的索引,值與Pattern.match()和Pattern.seach()方法的同名引數相同,
lastindex: 最后一個被捕獲的分組在文本中的索引,如果沒有被捕獲的分組,將為None,
lastgroup: 最后一個被捕獲的分組的別名,如果這個分組沒有別名或者沒有被捕獲的分組,將為None,
方法:
group([group1, …]):
獲得一個或多個分組截獲的字串;指定多個引數時將以元組形式回傳,group1可以使用編號也可以使用別名;編號0代表整個匹配的子串;不填寫引數時,回傳group(0);沒有截獲字串的組回傳None;截獲了多次的組回傳最后一次截獲的子串,
groups([default]):
以元組形式回傳全部分組截獲的字串,相當于呼叫group(1,2,…last),default表示沒有截獲字串的組以這個值替代,默認為None,
groupdict([default]):
回傳以有別名的組的別名為鍵、以該組截獲的子串為值的字典,沒有別名的組不包含在內,default含義同上,
start([group]):
回傳指定的組截獲的子串在string中的起始索引(子串第一個字符的索引),group默認值為0,
end([group]):
回傳指定的組截獲的子串在string中的結束索引(子串最后一個字符的索引+1),group默認值為0,
span([group]):
回傳(start(group), end(group)),
expand(template):
將匹配到的分組代入template中然后回傳,template中可以使用id或g、g參考分組,但不能使用編號0,id與g是等價的;但10將被認為是第10個分組,如果你想表達1之后是字符'0',只能使用g<1>0,
下面來用一個py實體輸出所有的內容加深理解:
代碼如下:
# -*- coding: utf-8 -*-
#一個簡單的match實體
import re
# 匹配如下內容:單詞+空格+單詞+任意字符
m = re.match(r'(w+) (w+)(?P.*)', 'hello world!')
print "m.string:", m.string
print "m.re:", m.re
print "m.pos:", m.pos
print "m.endpos:", m.endpos
print "m.lastindex:", m.lastindex
print "m.lastgroup:", m.lastgroup
print "m.group():", m.group()
print "m.group(1,2):", m.group(1, 2)
print "m.groups():", m.groups()
print "m.groupdict():", m.groupdict()
print "m.start(2):", m.start(2)
print "m.end(2):", m.end(2)
print "m.span(2):", m.span(2)
print r"m.expand(r'g<2> g<1>g<3>'):", m.expand(r'2 13')
### output ###
# m.string: hello world!
# m.re: <_sre.SRE_Pattern object at 0x016E1A38>
# m.pos: 0
# m.endpos: 12
# m.lastindex: 3
# m.lastgroup: sign
# m.group(1,2): ('hello', 'world')
# m.groups(): ('hello', 'world', '!')
# m.groupdict(): {'sign': '!'}
# m.start(2): 6
# m.end(2): 11
# m.span(2): (6, 11)
# m.expand(r'2 13'): world hello!
2.3. Pattern
Pattern物件是一個編譯好的正則運算式,通過Pattern提供的一系列方法可以對文本進行匹配查找,
Pattern不能直接實體化,必須使用re.compile()進行構造,也就是re.compile()回傳的物件,
Pattern提供了幾個可讀屬性用于獲取運算式的相關資訊:
pattern: 編譯時用的運算式字串,
flags: 編譯時用的匹配模式,數字形式,
groups: 運算式中分組的數量,
groupindex: 以運算式中有別名的組的別名為鍵、以該組對應的編號為值的字典,沒有別名的組不包含在內,
可以用下面這個例子查看pattern的屬性:
代碼如下:
# -*- coding: utf-8 -*-
#一個簡單的pattern實體
import re
p = re.compile(r'(w+) (w+)(?P.*)', re.DOTALL)
print "p.pattern:", p.pattern
print "p.flags:", p.flags
print "p.groups:", p.groups
print "p.groupindex:", p.groupindex
### output ###
# p.pattern: (w+) (w+)(?P.*)
# p.flags: 16
# p.groups: 3
# p.groupindex: {'sign': 3}
最后注意:光理論是不夠的,這里順便送大家一套2020最新python入門到高級專案實戰視頻教程,可以去小編的Python交流.裙 :七衣衣九七七巴而五(數字的諧音)轉換下可以找到了,還可以跟老司機交流討教!
本文的文字及圖片來源于網路加上自己的想法,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/141419.html
標籤:Python
下一篇:Python基礎-12決議式
