若是把BeautifulSopu比喻成經過線索一步步接近目標的偵探的話,那麼正則表達式就是牛逼哄哄的「天眼系統」,只要提供一些目標的特徵,不管搜索範圍多大,只要存在那麼一兩個符合特徵的目標,全都會被它直接逮住。html
這麼強大的方法是否是看到都心動了,不過強大是有代價的,較難上手很難精通這兩根大棒一會兒錘走了很多初學者。當時學的我是這樣的:python
抽象&可讀性差。爲了逮住某個目標,你可能要寫一條長長的,看到本身都頭暈的正則表達式,看上去就像亂碼同樣。舉個栗子,若是你要匹配一個ip地址,正則表達式會是這樣正則表達式
匹配ip地址: ((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)) ——真·亂碼
若是有足夠的自信和毅力不被正則擊倒,那就來吧。(屁,學正則還不是早晚的事!)後端
python 自帶模塊,直接導入便可。有匹配,替換等方法。
思考了許久後筆者以爲仍是先講表達式(規則)好,由於某些方法的理解是要了解表達式的。
下文的規則是徹底版的,花了好久寫成,分享給讀者,順便當成本身的網上筆記。學習
若是你學正則只是單單用來爬蟲的話,你只要熟悉「字符匹配」,「分組&或&轉義」,「預約字符集」,「數量詞」,「非貪婪模式」和(?:)取消分組,瞭解(或乾脆不學)「邊界匹配」,「特殊構造」就好了。優化
若是你以爲正則是你將來工做的剛需的話,推薦熟悉全部規則。spa
規則實際上是一個原字符串如r'表達式'/r"表達式",較正式的叫法是模式字符串。最後再說一句,匹配以單個字符爲單位(除括號能把多個字符打包成分組(總體)來匹配)
表達式本質是字符串,不要單引(雙引)號裏套單引(雙引)號,會出錯。code
r'[abcd]'#匹配一個a或b或c或d r'[0-9]'#匹配一個0至9的數,-的做用域是左右各一個字符 r'[a-z]' r'[A-Z]'#分別匹配a到z或A到Z的一個字母 r'[12-89]'#注意由於是單字符匹配,匹配的是1,2到8的數,9(即1到9的一個數),不是12到89的數 r'[{.|()^*+?$\\]'#匹配 { . | ( ) ^ * + ? $ \中任一個,\要轉義 r'[^a-zA-Z]'#匹配一個不是字母的字符
r'abc|def|ghi'#匹配abc或def或ghi r'ma(?:k|d)e'#匹配make或made r'(abc)def\1'#至關於r'(abc)defabc',匹配abcdefabc r'(?P<ok>abc)f(?P=ok)'#爲(abc)子組分配了「ok」的名字,而後再引用,匹配abcfabc
r'\w' #能匹配'物語&ものがたり'中的:物,語,も,の,が,た,り,漢語日語的單字,其餘語言同理
r'z{3}'#匹配zzz r'z{0,3}'#匹配z或zz或zzz r'(?:abc){2}'#對子表達式匹配兩次,匹配abcabc,(?:)是一個用法,不分組的意思,詳看後面 #星號加號問號同理
r'<.+>'#默認貪婪,對於'<abc><def>'能匹配到'<abc><def>'整條,由於.貪婪地把尖括號也匹配掉了 r'<.+?>'#非貪婪,對於'<abc><def>'能匹配到'<abc>'和'<def>'
r'^abc|^def'#匹配abc開頭或def開頭,開啓了多行模式時,對字符串'abcd\ndefh'能匹配出abc,def兩個 r'abc$|def$'#匹配abc結尾或def結尾,開啓了多行模式時,對字符串'0abc\n0def'能匹配出abc,def兩個 r'\Aabc'#匹配abc開頭,由於不能多行匹配,就算開啓多行模式,對字符串'abcd\nabcd'只能匹配到前面的abc #\Z同理 r'\w\b\W'#匹配「單詞字符+非單詞字符」的結構如'a!','1%' #\B同理
r'(ab(?=cde))'#匹配後面是bcd的ab r'a(?!\d+)'#匹配後面不跟一串數字的a,後括號可用全部數量詞 r'(?<=abc)de'#匹配前面是abc的de r'(?<!\d{3})a'#匹配前面不是三個數字的a,前括號能夠用{n}可是不能用不定量的數量詞
r'(?i)abc'#「i」對應re.I,忽略大小寫模式,能匹配Abc,ABC,abc等
相比於繁雜的規則,方法則要簡單多了,經常使用的就這幾個:htm
re.finditer(pattern,string,flags=0),同findall功能,可是返回的是迭代器對象
re.findall(r'\d+(abc)\d+','1abc1,2abc2')#分組爲(abc),findall只捕捉被數字包起來的abc返回列表['abc','abc'] re.findall(r'((?:ab){2}\d)\d','abab11,abab22')#整個表達式匹配abab加一個兩位數,(?:)取消了ab的分組,findall只捕捉abab加一個數,返回列表['abab1','abab2']
參數:
flags:模式(標籤),接受如下模式,多個模式用「|」分開如 flags=re.I|re.M
列出經常使用方法,下面的match是對象
地獄之旅到這就結束了,不只是讀者的,仍是個人,お疲れ
文章過長,可能存在某些瑕疵和錯誤,歡迎提出
累成苟,最近並且要忙於學習,又被P大學事件噁心了一下,接下來的產能會降低,估計一個星期多一點更一次
正則慢慢學就行,正則的使用後面會有實例讓你們熟悉