1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Python入門系列24 - 正則表達式(二)

        共 4416字,需瀏覽 9分鐘

         ·

        2019-10-19 09:50

        Python入門系列24

        ca79373656df2cda12544fe94bf7bee2.webp

        正則表達式(二)


        本篇閱讀時間約為 11分鐘。


        1

        前言


        今天繼續(xù)來介紹一下python的正則表達式,回顧一下上次介紹的re模塊整篇文章圍繞著re.findall()來進行實例的講解,也就是所謂的查詢操作。為了便于回顧,這里給出鏈接:python入門系列23 - 正則表達式(一)


        2

        re模塊的sub函數(shù)


        sub:中文有代替的意思。使用re.sub()可以完成我們對原始字符串的替換操作!

        先來看下官方函數(shù)的參數(shù)解釋:


        re.sub(pattern, repl, string, count=0, flags=0)

        pattern : 正則中的模式字符串。

        repl : 替換的字符串,也可為一個函數(shù)。

        string : 要被查找替換的原始字符串。

        count : 模式匹配后替換的最大次數(shù),默認 0 表示替換所有的匹配。

        flags : 標志位,用于控制正則表達式的匹配方式,如:是否區(qū)分大小寫,多行匹配等等。(如:re.I 使匹配對大小寫不敏感)


        一大波實例來襲,做好準備喲!


        實例1(替換普通字符):


        假設我數(shù)學和英文考試都得了60分……然而我并不甘心,上天給了我一次作弊的機會,可以通過程序來替換分數(shù)!如何做呢?


        import re
        words = 'My math scored 60 points,My English has also scored 60 points.'
        # 可以看到我的count參數(shù)給出的是0# 默認匹配所有60分,修改為100分
        new_words = re.sub('60','100',words,0)
        print(new_words)

        >>> My math scored 100 points,My English has also scored 100 points.


        同理,若是只想修改數(shù)學成績,則將count參數(shù)改為1即可:


        e1f58e9f2ba48a48d634c5d56cb0743f.webp


        實例2(有邏輯的函數(shù)替換):


        假設我的數(shù)學成績考了85分!emmm相當不錯了,但是我依然想讓它增加5分,我愛數(shù)學!而英語這次考了100分,因為作弊了……為了不讓老師察覺,我決定偷偷降低點分數(shù)!兩種條件,如何才能使用sub函數(shù)來完成呢?別忘了我們的repl(replace)參數(shù)是可以傳遞函數(shù)的!這也是Python的一個特性,參數(shù)可以傳遞函數(shù),如下:


        import re
        def modify_score(score):
        ? ?print(score)
        ? ?new_socre = score.group() ? ?
        ? ?if int(new_socre) == 85: ? ? ? ?
        ? ? ? ?return '90'
        ? ?if int(new_socre) == 100: ? ? ? ?
        ? ? ? ?return '80'

        words = 'My math scored 85 points,My English scored 100 points.That\'s cool!'
        new_words = re.sub('\d{2,3}',modify_score,words,0)
        print(new_words)


        c92266fb86c030416adf8edbc4a658b1.webp


        講解一下:在modify_score中,使用傳入score,可以打印輸出看下它的類型,這是一種正則的類型,而非字符串類型。此類型要將其內(nèi)容本身匹配出來,則需要調(diào)用它的group()方法,new_score取出來的便是數(shù)字形式的字符串。下面的邏輯對比,需要將字符串轉換為int型,才可以進行對比操作,否則會報錯喲。


        綜上所述: re.sub()可以輕松的實現(xiàn)字符串的替換,并且可以用函數(shù)傳遞的方式來對原始字符串進行業(yè)務邏輯的判斷。


        3

        re模塊其它常用函數(shù)


        1. match

        依然是用事例來解釋看下:


        import re
        words = 'My math scored 85 points,My English scored 100 points.That\'s cool!'
        new_words = re.match('\d{2,3}',words)
        print(new_words)

        >>> None


        上述結果,打印為None,Why???

        因為match函數(shù)在進行匹配的時候,是從字符串的起始開始進行匹配,若開頭的字符串不符合正則表達式,則直接返回None,也就是什么都沒匹配到,停止后續(xù)匹配。


        所以如果修改words,讓我們的分數(shù)在字符串開頭試下:

        68cd995793ffa5bb64d6032e7d36263f.webp


        2. search

        使用search的示例如下:


        import re
        words = 'My math scored 85 points,My English scored 100 points.That\'s cool!'
        new_words = re.search('\d{2,3}',words)
        print(new_words)
        print(new_words.group())

        >>> <_sre.SRE_Match object; span=(15, 17), match='85'>
        >>> 85


        上述結果,打印出了匹配到的對象與值,與match不一樣!但是可以看到,search函數(shù)只匹配到了一次的,后續(xù)分數(shù)的100即使符合正則表達式,也不會被匹配到了。


        match和search函數(shù)是當今市場上各教程類中,寫爬蟲最常用的兩個方法,而實際上這兩個函數(shù)是需要對匹配后的結果進行group分組處理,才能取出你想要的結果。在上節(jié)的小課堂中,全篇講到的findall方法,則不需要進行group的調(diào)用,可以直接將結果以list全面匹配出來,這也是findall和match、search函數(shù)最大的區(qū)別。


        4

        group分組


        既然提到了group分組,那么就來介紹下,group的具體用法,以及在爬蟲中經(jīng)常會以一種什么樣的方式去進行你想要的匹配!


        此處以search函數(shù)來舉例,場景是醬紫的:我自己說了一句話 ,「我在這次考試中,數(shù)學分數(shù)考了85,英語分數(shù)考了100分,這真是太酷了!」?,F(xiàn)在需要將英語分數(shù)考了100分」獲取到!代碼如下:


        import re
        words = 'My math scored 85 points,My English scored 100 points.That\'s cool!'

        new_words1 = re.search('points,\wThat',words)
        new_words2 = re.search('points,\w*That',words)
        new_words3 = re.search('points,.*That',words)
        new_words4 = re.search(',(.*)That',words)

        print(new_words1.group())
        print(new_words2.group())
        print(new_words3.group())
        print(new_words4.group())


        仔細看過代碼的同學,肯定會疑惑為什么寫了這么多行正則匹配的表達式,莫急莫急,且聽我慢慢道來。在不看我下面的解釋前,你認為,下面這四個print()會依次打印出什么樣的結果呢?


        解釋:其實new_words1~4是一段非常有邏輯的演變過程。

        ① 先來看new_word1,如果想要匹配我英語分數(shù)考了100分這段英文字符,需要先使用普通字符串進行邊界的限定,還記得嗎?(上節(jié)小課堂有說過哦!忘了的話回到文章首處點擊鏈接進行回顧。) 所以使用"ponit, ""That"進行邊界限定,一旦邊界限定后,便可以使用元字符來進行內(nèi)容的匹配,而\w代表的含義是匹配包括下劃線的任何單詞字符。于是調(diào)用如下圖:


        ebd0de30ece904e56b1c956be2f1d182.webp


        可以看到報錯啦,錯誤說的是None類型沒有group方法,因為1中的正則是錯誤的,沒有正確進行匹配,所以最終得到的值是None。理由很簡單,因為\w這樣的寫法只進行了單字符匹配,故然是不行的。如何進行多字符匹配呢?于是有了new_word2。


        ②?來看new_word2,普通字符的邊界限定寫法是不變的,在原來的基礎上,在\w后面新增*。*的元字符代表的含義是匹配前一個字符0次或n次以上。然后有了下圖:


        32c3552abaa2d063d2760b05a9ff0489.webp


        為毛還是報錯?然后在反思下,發(fā)現(xiàn)。。。哦原來是想匹配的字符串中是包含空格的,而\w是不能匹配到空格字符的,所以這個正則表達式的寫法依然不對!再繼續(xù),什么元字符可以進行空格和字母的匹配呢?于是有了new_words3。


        ③?new_words3中使用的是.來進行空格和字母的匹配,點的后面還是使用*來匹配。如下圖:


        ab83990459f4f059ec35f241bab71182.webp

        可以看到正確的結果了,終于沒有報錯了!但是呢,但是呢,但是呢。。。會發(fā)現(xiàn),匹配到的結果卻不是我想要的最終結果,它把整個正則表達式的限定邊界也匹配到了...于是再次改進,就有了最后的new_words4。


        ④ new_words4是在③的基礎上,除去了邊界字符的限定,將.*小括號擴了起來,此處就是在上節(jié)小課堂中提到的分組!而一旦分好組之后,我們便可以通過group將自己定義好的分組提取出來,清理下以上注釋掉的代碼:


        import re
        words = 'My math scored 85 points,My English scored 100 points.That\'s cool!'
        new_words4 = re.search(',(.*)That',words)
        print(new_words4)
        print(new_words4.group())
        print(new_words4.group(0))
        print(new_words4.group(1))


        76548049f4f5fca60a6fa0480467d78f.webp


        不難發(fā)現(xiàn),其實group()中是可以傳遞數(shù)字的,默認情況下不寫等同于0,可以看到上圖不寫和寫0是一個輸出結果。這里需要說下,為什么0匹配出來的是整段正則表達式的字符串,而不是我想要的“My English scored 100 points.”這句話。先來看下兩段代碼:

        new_words4 = re.search(',(.*)That',words)
        new_words5 = re.search('(,(.*)That)',words)


        實際上,new_words4是等效于new_words5的,在new_words5中默認的正則參數(shù)位置是有一層隱形的小括號,也就是最外面的組,所以當我們調(diào)用group(0)或者group()實則是指這層組的關系。


        若想調(diào)用組中組,需要從左到右,數(shù)字是從1開始進行調(diào)用的,和上面的代碼結果圖的最后一行是對應上的!


        5

        總結


        到這里,關于Python的正則表達式常用的幾點也就介紹完了,為什么要講述正則呢?因為這是處理字符串文本必不可少的一個強大工具!只要能得心應手的使用它,相信不論是在處理爬蟲想要的信息也好,數(shù)據(jù)清洗時處理也罷,都可以輕松玩轉字符串!


        用思維導圖來回顧下正表達式的所有常用知識點吧,所謂一圖勝過千言萬語,畢竟可以來梳理思路


        9b1ca0b9a54d8eb8c7440038f88f82f8.webp


        至此完!

        瀏覽 66
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            娇妻舞厅里的性呻吟 | 老鸭窝AV成人毛片免费观看 | 秘 黄 视频免费看在线 | 91视频在线观看18 | 中文字幕日韩精品欧美一区蜜桃网 | 99热99精品| 挺进江湖女侠美妇翘臀深处 | 亚洲手机在线观看 | 奇米网狠狠干 | 欧美粗大在线观看 |