Python爬虫自学之第(④)篇——强大的正则表达式,re模块
題外話:
《Pi Network 免費(fèi)挖礦國外熱門項目 一個π幣大約值3元到10元》相信過去BTC的人,信不信未來的PI,了解一下,唯一一個高度與之持平的項目
?
如果把BeautifulSopu比喻成通過線索一步步接近目標(biāo)的偵探的話,那么正則表達(dá)式就是牛逼哄哄的“天眼系統(tǒng)”,只要提供一些目標(biāo)的特征,無論搜索范圍多大,只要存在那么一兩個符合特征的目標(biāo),全都會被它直接逮住。
?
特性
牛逼王
- BS的爸爸,我告訴你個秘密,其實(shí)BeautifulSoup也是用正則實(shí)現(xiàn)的,而且它find_all的參數(shù)里還能接收正則呢
- 信息精確定位,BeautifulSoup用的是節(jié)點(diǎn)定位,可能會出現(xiàn)多個符合條件的節(jié)點(diǎn)(卻沒有目標(biāo)信息);正則是直接針對目標(biāo)信息,以字符為單位匹配,一次篩選出正確結(jié)果(前提是寫好正則)
- 能獲取信息的部分,有時候完整的信息不是你想要的,你只想取它的某一部分,正則能搞定,BS只能先獲取完整信息再分離。
- 用途大著呢,不要以為正則只能爬蟲,前后端都少不了正則,你填個信息判斷是否合法這都是正則,總之學(xué)到賺到啊
勸退大王+
這么強(qiáng)大的方法是不是看到都心動了,不過強(qiáng)大是有代價的,較難上手很難精通這兩根大棒一下子錘走了不少初學(xué)者。當(dāng)時學(xué)的我是這樣的:
-
抽象&可讀性差。為了逮住某個目標(biāo),你可能要寫一條長長的,看到自己都頭暈的正則表達(dá)式,看上去就像亂碼一樣。舉個栗子,如果你要匹配一個ip地址,正則表達(dá)式會是這樣
匹配ip地址:((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)) ——真·亂碼 - 編寫時出錯率高,新手很難一次寫對,需要不停地修改幾次十幾次才能pass(大腦在顫抖)
- 難于優(yōu)化,優(yōu)化好的正則能提高匹配速度,然而你這新手還想優(yōu)化,能匹配對就很不錯了(正則暗中偷笑)
如果有足夠的自信和毅力不被正則擊倒,那就來吧。(屁,學(xué)正則還不是遲早的事!)
re 模塊
python 自帶模塊,直接導(dǎo)入即可。有匹配,替換等方法。
思考了許久后筆者覺得還是先講表達(dá)式(規(guī)則)好,因?yàn)槟承┓椒ǖ睦斫馐且私獗磉_(dá)式的。
下文的規(guī)則是完全版的,花了很久寫成,分享給讀者,順便當(dāng)成自己的網(wǎng)上筆記。
如果你學(xué)正則只是單單用來爬蟲的話,你只要熟悉“字符匹配”,“分組&或&轉(zhuǎn)義”,“預(yù)定字符集”,“數(shù)量詞”,“非貪婪模式”和(?:)取消分組,了解(或干脆不學(xué))“邊界匹配”,“特殊構(gòu)造”就行了。
如果你覺得正則是你未來工作的剛需的話,推薦熟悉所有規(guī)則。
匹配規(guī)則(pattern)
規(guī)則其實(shí)是一個原字符串如r'表達(dá)式'/r"表達(dá)式",較正式的叫法是模式字符串。最后再說一句,匹配以單個字符為單位(除括號能把多個字符打包成分組(整體)來匹配)
表達(dá)式本質(zhì)是字符串,不要單引(雙引)號里套單引(雙引)號,會出錯。
字符匹配
- 任一字符(空格也算)——就是匹配這個字符,某些字符因?yàn)樵谡齽t中有特殊用途需前加反斜杠轉(zhuǎn)義如 [ { . | ( ) ^ * + ? $
- .——英文句號,匹配除換行符\n外的任意單個字符
- []——匹配中括號里的任一字符,與-結(jié)合還能表示范圍內(nèi)的任一字符,中括號內(nèi)的字符除\外會自動轉(zhuǎn)義,還有小心多個中括號嵌套錯誤
- [^]——中括號最前面加^,與[ ]反義,匹配一個不在中括號里的字符,也可以用橫杠-
分組&或&轉(zhuǎn)義
- ()——括號,表達(dá)式分組(第n組,n=1,2,3....99,從左往右數(shù)),并形成子表達(dá)式
- (?P<name>)——擁有括號的功能,但能為該分組再指定一個自定名字
- (?P=name)——引用分配過名字的分組,但沒有分組功能
- |——或,左右規(guī)則任意匹配一個,從左往右嘗試匹配,一旦成功就跳過后面的規(guī)則。|沒被包在括號中間的話它的作用域是整個表達(dá)式,被包的話作用域在括號內(nèi)
- \——反斜杠,后接功能字有符轉(zhuǎn)義功能,后接數(shù)字(1到99)有引用分組的功能,后接某些字母又有特殊功能
預(yù)定字符集
- \d——匹配任一個數(shù)字(0~9)
- \D——匹配一個非數(shù)字字符,與\d互補(bǔ)
- \s——匹配一個空白字符,包括空格,\t,\n,\r,\n,\f,\v
- \S——匹配一個非空白字符
- \w——匹配一個單詞字符。unicode下匹配各種語言的單個字符,單個數(shù)字,和下橫線。ASCII下匹配單個英文字母,單個數(shù)字,和下橫線
- \W——匹配一個非單詞字符
數(shù)量詞(接在字符或子組后)
- {n}——作用于前一個字符或子表達(dá)式,匹配它重復(fù)n次
- {min,max}——作用于前一個字符或子表達(dá)式,匹配它重復(fù)重復(fù)多少次min~max次,min和max可只寫一個設(shè)置重復(fù)下限或上限,但逗號不能省,不寫min時min默認(rèn)為0
- *——星號,作用于前一個字符或子表達(dá)式,匹配它零次或多次
- +——作用于前一個字符或子表達(dá)式,匹配它至少一次
- ?——作用于前一個字符或子表達(dá)式,匹配它零次或一次
非貪婪模式
- 在數(shù)量詞后接?,對前面的數(shù)量詞開啟非貪婪模式,意思就是在能匹配的前提下盡可能少的重復(fù)匹配。
- 正則默認(rèn)開啟貪婪模式
邊界匹配
- ^——放在表達(dá)式的最前面,作用域是表達(dá)式,在多行模式中,在每一行匹配字符串開頭(多行模式要手動開啟,否則和\A沒什么區(qū)別)
- $——放在表達(dá)式的最后面,作用域是表達(dá)式,在多行模式中,在每一行匹配字符串末尾(多行模式要手動開啟,否則和\Z沒什么區(qū)別)
- \A——放在表達(dá)式的最前面,作用域是表達(dá)式,匹配字符串開頭,不能多行匹配
- \Z——放在表達(dá)式的最后面,作用域是表達(dá)式,匹配字符串末尾,不能多行匹配
- \b——不匹配字符,只匹配一個邊界,匹配\w和\W或\W和\w的邊界(單詞字符和非單詞字符的邊界)
- \B——不匹配字符,只匹配一個邊界,與\b相反,匹配\w和\w或\W和\W的邊界
特殊構(gòu)造(不作為分組,不被findall捕獲)
-
- (?:)——取消括號的分組功能,使其不會被findall方法捕獲
- (?#)——#后寫注釋內(nèi)容,整個(?#)會被忽略
- A(?=)——A之后的字符串需要匹配括號里的表達(dá)式A才會被匹配,一定用在表達(dá)式的最后(A是表達(dá)式,(?=)內(nèi)的表達(dá)式不會被匹配捕捉,下同)
- A(?!)——A之后的字符串需要不匹配括號里的表達(dá)式A才會被匹配,一定用在表達(dá)式的最后
- (?<=)A——A之前的字符串需要匹配括號里的表達(dá)式A才會被匹配,一定用在表達(dá)式的最前,括號內(nèi)的表達(dá)式需固定長度不能使用除{n}外的數(shù)量詞
- (?<!)A——A之前的字符串需要不匹配括號里的表達(dá)式A才會被匹配,一定用在表達(dá)式的最前,括號內(nèi)的表達(dá)式需固定長度不能使用除{n}外的數(shù)量詞
- ?(?iLmsux)——放在表達(dá)式最前面,為所在的表達(dá)式設(shè)置模式,”i”, “L”, “m”, “s”, “u”, “x”,它們不匹配任何字串,對應(yīng)python中re模塊當(dāng)中的(re.I, re.L, re.M, re.S, re.U, re.X)的6種模式,下面flag參數(shù)講
方法&參數(shù)
相比于繁雜的規(guī)則,方法則要簡單多了,常用的就這幾個:
- re.search(pattern,string,flags=0),返回第一個匹配的match對象(內(nèi)含匹配字符串的信息)
- re.findall(pattern,string,flags=0),返回所有匹配分組的字符串組成的列表,沒設(shè)置分組相當(dāng)于整個表達(dá)式就是一個分組
- #如果表達(dá)式有多個分組,會返回復(fù)雜的列表,因此findall中的表達(dá)式通常只有一個分組
-
re.finditer(pattern,string,flags=0),同findall功能,但是返回的是迭代器
- pattern = re.compile(pattern,flags=0),把規(guī)則打包返回(如多次使用該規(guī)則),相當(dāng)與pattern和flag的合體,當(dāng)成pattern使用可免去設(shè)置flags
- re.sub(pattern,repl,string,count=0,flags)把匹配到的部分用指定字符串repl替換,count設(shè)置替換次數(shù),默認(rèn)為零替換所有
參數(shù):
- pattern:接收模式字符串,即表達(dá)式,也可以接收打包的規(guī)則
- string:接收待匹配字符串,如html文檔
-
flags:模式(標(biāo)簽),接受以下模式,多個模式用“|”分開如 flags=re.I|re.M
- re.I = re.IGNORECASE ? 忽略大小寫
- re.L = re.LOCALE ? 支持當(dāng)前語言,為了支持多語言版本的字符集使用環(huán)境
- re.U = re.UNICODE ? 使用w,W,b,B這些元字符時將按照UNICODE定義的屬性
- re.M = re.MULTILINE ? 開啟多行模式
- re.S = re.DOTALL ? 使.能匹配換行符\n
- re.X = re.VERBOSE ? 可以忽略正則表達(dá)式中的空白和#號的注釋,不匹配空格和#注釋
- re.A ?開啟ASCII模式
match對象方法
列出常用方法,下面的match是對象
- match.group(id/name)id是分組序號(1~99),name是分組的自定名字,返回指定分組的字符串;不傳參數(shù)數(shù)是返回整條匹配字符串
- match.start(id/name),match.end(id/name),match.span(id/name),分別返回指定分組字符串在整個字符串中的開始位置,結(jié)束位置,范圍。
正則慢慢學(xué)就行,正則的使用后面會有實(shí)例讓大家熟悉
總結(jié)
以上是生活随笔為你收集整理的Python爬虫自学之第(④)篇——强大的正则表达式,re模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu14.04 boost动态库
- 下一篇: 用Python批量下载MOOC资源