正則


#--Name: 正則


0x00 什麼是正則表達式?

    正則表達式是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符,

    以及這些特定字符的組合,組成一個  "規則字符串",這個  "規則字符串"用來

    表達對字符串的一種過濾邏輯


    特別需要注意的是:

        正則表達式非Python獨有,re模塊實現


0x01 在線正則表達式測試

    http://tool.oschina.net/regex/


0x02 python中re模塊 match 方法

    #re.match 嘗試從字符串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就會返回none

    re.match(pattern,string,flags=0)


0x03 re.match的相關實例

    #最常規的匹配

    import re


    content = 'Hello 123 4567 World_This is a Regex Demo'

    print(len(content))

    result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}.*Demo$',content)

    print(result)

    print(result.group())

    print(result.span())



    #泛匹配 如果上面的匹配你覺得太過於冗長,那麼可是使用泛匹配 '  .*  '

    import re

    content = 'Hello 123 4567 World_This is a Regex Demo'

    result = re.match('^Hello.*Demo$',content)

    print(result)

    print(result.group())

    print(result.span())


    #匹配目標

    import re

    

    content = 'Hello 1234567 World_This is a Regex Demo'

    result = re.match('^Hello\s(\d+)\sWorld.*Demo$',content)

    print(result)

    print(result.group())  # 打印全部

    print(result.group(1)) # 打印第1個括號內的匹配結果,如果表達式中有多個括號,第一個括號內的結果就是group(1)

    #第二個括號內的結果就是group(2),以此類推

    print(result.span())


    #貪婪匹配  使用   '  .*  ' 儘可能匹配多的字符

    import re

    

    content = 'Hello 1234567 World_This is a Regex Demo'

    result = re.match('^He.*(\d+).*Demo$',content)

    print(result.group(1))


    #非貪婪匹配  使用 '  .*?  ' 儘可能匹配少的字符

    import re

    

    content = 'Hello 1234567 World_This is a Regex Demo'

    result = re.match('^He.*?(\d+).*Demo$',content)

    print(result.group(1))


    

    #匹配模式   .* 除了換行符之外,可以匹配任意字符,需要匹配換行時,則需要指定  '  re.S  ' 模式

    import re

    

    content = '''Hello 1234567 World_This 

    is a Regex Demo

    '''

    result = re.match('^He.*?(\d+).*?Demo$',content,re.S)

    print(result.group(1))




    #轉義

    #用例1: 在不轉意的情況下

    import re


    content = 'price is $5.00'

    result = re.match('price is $5.00',content)

    print(result)


    #用例2: 加入轉義

    import re


    content = 'price is $5.00'

    result = re.match('price is \$5\.00',content)

    print(result)



    #總結: 在實際的使用中 儘量使用泛匹配, 使用括號得到匹配目標, 儘量使用非貪婪模式, 有換行符就用 re.S








0x04 re.search 使用實例

    #re.search 掃描整個字符串並返回第一個成功的匹配


    #用例1: 使用re.match方法

    import re


    content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'

    result = re.match('Hello.*?(\d+).*?Demo',content)

    print(result)


    #用例2: 使用re.search方法

    import re


    content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'

    result = re.search('Hello.*?(\d+).*?Demo',content)

    print(result)

    print(result.group(1))


    #總結: 爲了匹配方便,在能用search方法的場景下,就不用match


0x05 匹配演練

    #匹配1: 匹配 有active的li標籤

    import re


    html = '''<div id='songs-list'>

        <h2 class='title'>經典老歌</h2>

        <p class='introduction'>

            經典老歌列表

        </p>

        <ul id='list' class='list-group'>

        <li data-view='2'>一路上有你</li>

        <li data-view='7'>

            <a href='/2.mp3' singer='任賢齊'>滄海一聲笑</a>

        </li>

        <li data-view='4' class='active'>

            <a href='/3.mp3' singer='齊秦'>往事隨風</a>

        </li>

        <li data-view='6'><a href='/4.mp3' singer='beyond'>光輝歲月</a></li>

        <li data-view='5'><a href='/5.mp3' singer='陳慧琳'>記事本</a></li>

        <li data-view='5'>

            <a href='/6.mp3' singer='鄧麗君'><i class='fa fa-user'></i>但願人長久</a>

        </li>

        </ul>

    </div>'''

    result = re.search("<li.*?active.*?singer='(.*?)'>(.*?)</a>", html, re.S)

    if result:

        print(result.group(1), result.group(2))


    #匹配: 匹配第二個li標籤

    import re


    html = '''<div id='songs-list'>

        <h2 class='title'>經典老歌</h2>

        <p class='introduction'>

            經典老歌列表

        </p>

        <ul id='list' class='list-group'>

        <li data-view='2'>一路上有你</li>

        <li data-view='7'>

            <a href='/2.mp3' singer='任賢齊'>滄海一聲笑</a>

        </li>

        <li data-view='4' class='active'>

            <a href='/3.mp3' singer='齊秦'>往事隨風</a>

        </li>

        <li data-view='6'><a href='/4.mp3' singer='beyond'>光輝歲月</a></li>

        <li data-view='5'><a href='/5.mp3' singer='陳慧琳'>記事本</a></li>

        <li data-view='5'>

            <a href='/6.mp3' singer='鄧麗君'><i class='fa fa-user'></i>但願人長久</a>

        </li>

        </ul>

    </div>'''

    result = re.search("<li.*?singer='(.*?)'>(.*?)</a>", html, re.S)

    if result:

        print(result.group(1), result.group(2))



    #匹配: 匹配有完整歌曲信息的第三個li標籤 

    import re


    html = '''<div id='songs-list'>

        <h2 class='title'>經典老歌</h2>

        <p class='introduction'>

            經典老歌列表

        </p>

        <ul id='list' class='list-group'>

        <li data-view='2'>一路上有你</li>

        <li data-view='7'>

            <a href='/2.mp3' singer='任賢齊'>滄海一聲笑</a>

        </li>

        <li data-view='4' class='active'>

            <a href='/3.mp3' singer='齊秦'>往事隨風</a>

        </li>

        <li data-view='6'><a href='/4.mp3' singer='beyond'>光輝歲月</a></li>

        <li data-view='5'><a href='/5.mp3' singer='陳慧琳'>記事本</a></li>

        <li data-view='5'>

            <a href='/6.mp3' singer='鄧麗君'><i class='fa fa-user'></i>但願人長久</a>

        </li>

        </ul>

    </div>'''

    result = re.search("<li.*?singer='(.*?)'>(.*?)</a>", html)

    if result:

        print(result.group(1), result.group(2))



0x06 re.findall 使用實例

    搜索字符串,以列表形式返回全部能匹配的子串

    查詢符合條件的所有結果


    #匹配: 匹配出所有的歌曲鏈接 歌手名稱 歌曲名稱

    import re


    html = '''<div id='songs-list'>

        <h2 class='title'>經典老歌</h2>

        <p class='introduction'>

            經典老歌列表

        </p>

        <ul id='list' class='list-group'>

        <li data-view='2'>一路上有你</li>

        <li data-view='7'>

            <a href='/2.mp3' singer='任賢齊'>滄海一聲笑</a>

        </li>

        <li data-view='4' class='active'>

            <a href='/3.mp3' singer='齊秦'>往事隨風</a>

        </li>

        <li data-view='6'><a href='/4.mp3' singer='beyond'>光輝歲月</a></li>

        <li data-view='5'><a href='/5.mp3' singer='陳慧琳'>記事本</a></li>

        <li data-view='5'>

            <a href='/6.mp3' singer='鄧麗君'>但願人長久</a>

        </li>

        </ul>

    </div>'''

    results = re.findall("<li.*?href='(.*?)'.*?singer='(.*?)'>(.*?)</a>",html,re.S)

    print(results)

    print(type(results))

    for result in results:

        print(result)


    #匹配: 匹配出所有有完整信息的歌曲名稱


    import re


    html = '''<div id='songs-list'>

        <h2 class='title'>經典老歌</h2>

        <p class='introduction'>

            經典老歌列表

        </p>

        <ul id='list' class='list-group'>

        <li data-view='2'>一路上有你</li>

        <li data-view='7'>

            <a href='/2.mp3' singer='任賢齊'>滄海一聲笑</a>

        </li>

        <li data-view='4' class='active'>

            <a href='/3.mp3' singer='齊秦'>往事隨風</a>

        </li>

        <li data-view='6'><a href='/4.mp3' singer='beyond'>光輝歲月</a></li>

        <li data-view='5'><a href='/5.mp3' singer='陳慧琳'>記事本</a></li>

        <li data-view='5'>

            <a href='/6.mp3' singer='鄧麗君'>但願人長久</a>

        </li>

        </ul>

    </div>'''

    results = re.findall("<li.*?>\s*?(<a.*?>)?(\w+)(</a>)?\s*?</li>",html, re.S)

    print(results)

    for result in results:

        print(result[1])



0x07 re.sub

     替換字符串中每一個匹配的字串後,返回替換後的字符串

    #用例1: 把其中的數字替換掉

    import re


    content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'

    result = re.sub('\d+','',content)

    print(result)


    #用例2: 把其中的數字替換成指定內容

    import re


    content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'

    result = re.sub('\d+','這裏以前是數字',content)

    print(result)


    #用例3: 被替換中的內容包含原內容的情況

    import re


    content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'

    result = re.sub('(\d+)',r'\1 8910',content)

    #值得注意的是,由於第二個參數中插入了轉義字符'\',爲了保證它的內容是原生內容,前面用了個 'r'

    #並且,前面的條件加了個小括號, 也就是 group(1)的意思

    print(result)


    #我們先把<a>標籤替換掉,再用findall方法提取數據

    #發現數據中存在換行符  \n  

    #我們再用 strip()方法去掉換行符

    import re


    html = '''<div id='songs-list'>

        <h2 class='title'>經典老歌</h2>

        <p class='introduction'>

            經典老歌列表

        </p>

        <ul id='list' class='list-group'>

        <li data-view='2'>一路上有你</li>

        <li data-view='7'>

            <a href='/2.mp3' singer='任賢齊'>滄海一聲笑</a>

        </li>

        <li data-view='4' class='active'>

            <a href='/3.mp3' singer='齊秦'>往事隨風</a>

        </li>

        <li data-view='6'><a href='/4.mp3' singer='beyond'>光輝歲月</a></li>

        <li data-view='5'><a href='/5.mp3' singer='陳慧琳'>記事本</a></li>

        <li data-view='5'>

            <a href='/6.mp3' singer='鄧麗君'>但願人長久</a>

        </li>

        </ul>

    </div>'''


    html = re.sub("<a.*?>|</a>",'',html)

    print(html)

    results = re.findall("<li.*?>(.*?)</li>",html,re.S)

    print(results)

    for result in results:

        print(result.strip())




0x08 re.compile,把字符串編譯成正則表達式對象

    #將一個正則表達式串編譯成正則對象,以便於複用該匹配模式

    

    #用例1:

    import re


    content = '''Hello 1234567 World_This

    is a Regex Demo'''

    pattern = re.compile('Hello.*Demo',re.S)

    #result = re.match('Hello.*Demo',content,re.S)

    #可以嘗試上面的寫法和下面的寫法用法是一樣的

    #爲什麼要這麼做? 這是爲了便於以後的代碼複用

    result = re.match(pattern,content)

    print(result)



0x09 實戰練習

    #綜合使用之前的方法 做一個豆瓣圖書的爬取

    import requests

    import re

    #該實例獲取豆瓣圖書的出版信息等等

    

    #請寫代碼實現,獲取鏈接url,書名,作者,出版日期,出版社,簡介

    #換行符號請使用 re.sub方法來實現

    #要使用re.compile


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章