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