1. 程式人生 > >模塊一(re模塊)

模塊一(re模塊)

bject 的區別 但是 top art 數字 decode 時間 pat

一、re模塊

首先說一下什麽是模塊,模塊就是一組功能的集合。你要和某個東西打交道,而這個東西本身和python沒關系,這個東西本身就存在,所以python提供了一個功能的集合專門負責和這個東西打交道。

模塊的類型:

內置模塊:不需要我們自己安裝,解釋器自帶的;

第三方模塊:需要我們自己安裝的模塊;

自定義模塊:我們自己寫的模塊;

為什麽要有模塊?先舉一個例子:我們都知道是操作系統把所有硬件管理起來的,文件是在硬盤上存儲的,python想從硬盤上進行文件的操作和刪除時就需要引入os模塊,說白了,模塊實際上就是給我們提供功能,這個要操作的內容本身就存在,模塊只不過是python提供給我們去操作這個內容的方法。

註意:永遠不要起一個和你已知的模塊同名的py文件的名字!

今天我們就來學習一下re模塊的幾個基礎方法,在python中使用正則表達式就要引入re模塊。

1,查找

  findall:表示匹配每一項都是列表中的一個元素。 (重要程度*****)

語法規則:re.findall(‘正則表達式’, 待匹配字符串 , flag),具體示例如下:

    import re
    ret = re.findall(\d+, sjkhk172按實際花費928)
    print(ret)  # 結果為:[‘172‘, ‘928‘]
        
    ret 
= re.findall(\d, sjkhk172按實際花費928) print(ret) # 結果為:[‘1‘, ‘7‘, ‘2‘, ‘9‘, ‘2‘, ‘8‘]

  search:只匹配從左到右的第一個,得到的不是直接的結果,而是一個變量,通過這個變量的group方法來獲取結果,如果沒有匹配到,會返回None,使用group會報錯。(重要程度*****)

語法規則:re.search(‘正則表達式’, 待匹配字符串 , flag),具體示例如下:

    ret = re.search(\d+, sjkhk172按實際花費928)
    print
(ret) # 結果為:<_sre.SRE_Match object; span=(5, 8), match=‘172‘> print(ret.group()) # 結果為:172 ret = re.search(\d,owghabDJLBNdgv) print(ret) # 結果為:None print(ret.group()) # 會報錯 # 因為search方法查找的時候,若待匹配的字符串中沒有能匹配到的結果時, # 用group會報錯,所以通常我們寫成下面這樣 ret = re.search(\d+,sjkhk172按實際花費928) if ret : # 內存地址,這是一個正則匹配的結果 print(ret.group()) # 通過ret.group()獲取真正的結果

  match:從頭開始匹配,相當於search中的正則表達式加上一個^。(重要程度**)

語法規則:re.match(‘正則表達式’, 待匹配字符串 , flag),具體示例如下:

    ret = re.match(\d+$,sjkhk172按實際花費928)
    print(ret)  # 結果為:None
    ret = re.match(\d+,172sjkhk按實際花費928)
    print(ret)  # 結果為:<_sre.SRE_Match object; span=(0, 3),     match=‘172‘>
    print(ret.group())  # 結果為:172
    ret = re.match(\d+$,172sjkhk按實際花費928)
    print(ret)  # 結果為:None

2,字符串處理的擴展

切割:re.split(‘正則表達式’, 待匹配字符串),用正則表達式匹配出來的結果對待匹配字符串切割。如下:

    s = alex83taibai40egon25
    ret = re.split(\d+,s)
    print(ret)  # 結果為:[‘alex‘, ‘taibai‘, ‘egon‘, ‘‘]

  替換:sub和subn

re.sub(‘正則表達式’, ‘新內容’, 待匹配字符串 , 替換次數)

    re.subn(‘正則表達式’, ‘新內容’, 待匹配字符串 , 替換次數) ,示例如下:

    ret = re.sub(\d+,H,alex83taibai40egon25)
    print(ret)  # 結果為:alexHtaibaiHegonH
    ret = re.sub(\d+,H,alex83taibai40egon25,1)
    print(ret)  # 結果為:alexHtaibai40egon25

    ret = re.subn(\d+,H,alex83taibai40egon25)
    print(ret)  # 結果為:(‘alexHtaibaiHegonH‘, 3)
    ret = re.subn(\d+,H,alex83taibai40egon25, 2)
    print(ret)  # 結果為:(‘alexHtaibaiHegonH‘, 2)
    # 我們可以看出sub和subn的區別是subn返回一個元組,元組第二個元素是替換次數。

3,re模塊的進階:時間和空間上更優化

compile:節省使用正則表達式解決問題的時間(編譯,就是將正則表達式編譯成字節碼,這樣在多次使用的過程中不會多次編譯,可以用這個結果去直接search、match、findall、finditer),具體示例如下:

    ret = re.compile(\d+)   # 編譯
    print(ret)  # 結果為:re.compile(‘\\d+‘)
    res = ret.findall(alex83taibai40egon25)  # 編譯後直接使用
    print(res)
    res = ret.search(sjkhk172按實際花費928)  # 編譯後直接使用
    print(res.group())

  finditer:節省使用正則表達式解決問題的空間/內存(返回一個叠代器,所有的結果都在這個叠代器中,可以通過循環和group取出來),具體示例如下:

    ret = re.finditer(\d+,alex83taibai40egon25)
    print(ret)  # 結果為:<callable_iterator object at 0x00000000029EFDA0>
    for i in ret:
        print(i.group())
    # 結果為:
    # 83
    # 40
    # 25

二、在python中使用正則表達式的特點和問題

1,分組在re模塊中的使用,分析如下幾段代碼,理解並總結規則:

    # 1 search方法中對正則分組,通過group(n)取出相應內容
    s = <a>wahaha</a>
    ret = re.search(<(\w+)>(\w+)</(\w+)>,s)
    print(ret.group())  # 結果為:<a>wahaha</a>,默認取出所有匹配內容
    print(ret.group(1)) # 數字參數代表的是取對應分組中的內容,結果為:a
    print(ret.group(2))  # 結果為:wahaha
    print(ret.group(3))  # 結果為:a

    # 2 findall也可以順利取到分組中的內容,因為它有一個特殊的語法,就是優先顯示分組中的內容
    ret = re.findall((\w+),s)
    print(ret)  # 結果為:[‘a‘, ‘wahaha‘, ‘a‘]
    ret = re.findall(>(\w+)<,s)
    print(ret)  # 結果為:[‘wahaha‘]

    # 3 取消分組優先(?:正則表達式)
    ret = re.findall(>(?:\w+)<,s)
    print(ret)  # 結果為:[‘>wahaha<‘]
    ret = re.findall(\d+(?:\.\d+)?,1.234*4)
    print(ret)   # 結果為:[‘1.234‘, ‘4‘]
    # 當你想用()表示正則裏的分組,而不想表示優先顯示的時候可以用?:取消分組

  綜上: 對於正則表達式來說,有些時候我們需要進行分組,來整體約束某一組字符出現的次數;對於python語言來說,分組可以幫助你更好更精準的找到你真正需要的內容;具體想表示哪種分組,要看情況決定。

    # 4 split方法中可以對正則加括號表示使切割的字符不丟失
    ret = re.split(\d+,alex83taibai40egon25)
    print(ret)  # 結果為:[‘alex‘, ‘taibai‘, ‘egon‘, ‘‘]
    ret = re.split((\d+),alex83taibai40egon25)
    print(ret)  # 結果為:[‘alex‘, ‘83‘, ‘taibai‘, ‘40‘, ‘egon‘, ‘25‘, ‘‘]

    # 分組命名 (?P<組名>正則表達式)
    s = <a>wahaha</a>
    ret = re.search(>(?P<con>\w+)<,s)
    print(ret.group(1))  # 結果為:wahaha
    print(ret.group(con))  # 結果為:wahaha

    # 使用前面的分組 要求使用這個名字的分組和前面同名分組中的內容匹配的必須一致
    pattern = <(?P<tab>\w+)>(\w+)</(?P=tab)>
    ret = re.search(pattern,s)
    print(ret.group())   # 結果為:<a>wahaha</a>
    # 可以練習下列的匹配:
    # 2018-12-06
    # 2018.12.6
    # 2018 12 06
    # 12:30:30

三、使用正則表達式的技巧

當你要匹配的內容太沒有特點,容易和你不想匹配的內容混在一起的時候,就可以把不想匹配的也取出來,然後通過python過濾掉,具體示例如下:

    # 想只取整數,但是會帶上小數,那麽把整數和小數都取出來,然後再過濾掉小數
    ret=re.findall(r"\d+\.\d+|\d+","1-2*(60+(-40.35/5)-(-4*3))")
    print(ret)  # 結果為:[‘1‘, ‘2‘, ‘60‘, ‘40.35‘, ‘5‘, ‘4‘, ‘3‘]
    ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
    ret.remove(‘‘)
    print(ret)  # 結果為:[‘1‘, ‘2‘, ‘60‘, ‘5‘, ‘4‘, ‘3‘]

四、爬蟲的例子

預備知識:如何獲取一個頁面的源代碼,如下可以做到:

    from urllib import request
    ret = request.urlopen(https://movie.douban.com/top250?    start=50&filter=)
    res = ret.read().decode(utf-8)
    print(res)

  分析並掌握如下爬蟲的小例子:

    import re
    from urllib.request import urlopen

    def getPage(url):   # 獲取網頁的字符串
        response = urlopen(url)
        return response.read().decode(utf-8)

    def parsePage(s):
        ret = com.finditer(s)  # 從s這個網頁源碼中 找到所有符合com正則表達式規則的內容 並且以叠代器的形式返回
        for i in ret:
            yield {
                "id": i.group("id"),
                "title": i.group("title"),
                "rating_num": i.group("rating_num"),
                "comment_num": i.group("comment_num"),
            }

    def main(num):  # 0  25 50  # 這個函數執行10次,每次爬取一頁的內容
        url = https://movie.douban.com/top250?start=%s&filter= % num
        response_html = getPage(url)   # response_html就是這個url對應的html代碼 就是 str
        ret = parsePage(response_html) # ret是一個生成器
        print(ret)
        f = open("move_info7", "a", encoding="utf8")
        for obj in ret:
            print(obj)
            data = str(obj)
            f.write(data + "\n")
        f.close()

    com = re.compile(
        <div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>
        .*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)評價</span>, re.S)

    count = 0
    for i in range(10):
        main(count)
        count += 25

寫在最後:

  正則表達式到底重要到什麽程度?

  掌握作業中的所有內容

  能夠看懂常用的正則表達式

  並且能夠做出一些公司特異性要求的修改

模塊一(re模塊)