1. 程式人生 > >Python基礎—15-正則表示式

Python基礎—15-正則表示式

正則表示式

應用場景

  • 特定規律字串的查詢替換切割等
  • 郵箱格式、URL、IP等的校驗
  • 爬蟲專案中,特定內容的提取

使用原則

  • 只要是能夠使用字串函式解決的問題,就不要使用正則
  • 正則的效率較低,還會降低程式碼的可讀性
  • 世界上最難理解的三樣東西:醫生的處方、道士的神符、碼農的正則
  • 提醒:正則是用來寫的,不是用來讀的;在不知道功能的情況下,不要試圖閱讀別人的正則。

基本使用

  • 說明:正則的解析處理是由re模組完成

  • 相關函式:

    • match:從開頭進行匹配,匹配到就返回正則結果物件,沒有就返回None
    • search:從任意位置匹配,匹配到一次就返回,沒有就返回None
    import re
    
    
    # 只從開頭匹配,找到返回一個正則結果物件,沒有找到返回None # m = re.match('abc', 'abcsdhasdasjabcweuqo') # 全部匹配,只要找到就停止並返回 m = re.search('abc', 'sdhabcsdasjabcweuqo') if m: # 提取匹配到的內容 print(m.group()) # 獲取匹配位置 print(m.span())
    • findall:全域性匹配,返回匹配到的結果列表,沒有時返回空列表
    # 匹配所有內容,返回匹配結果組成的列表,若沒有則返回空列表
    f = re.findall('
    abc', 'qwsdhaslabcsadjlasdoiabcdakls') if f: print(f) print(type(f))
    • compile:生成正則表示式物件
    # 生成正則表示式物件,用於正則匹配
    c = re.compile('hello')
    
    # 從開頭進行匹配
    # m = c.match('hellosdsjldkabc')
    # 從任意位置匹配
    m = c.search('shdjkhelloaskjdha')
    if m:
        print(m.group())
    # 匹配所有
    f = c.findall('helloasjdhakhello')
    
    if f: print(f)

    將正則的匹配分兩步完成:先建立正則物件,然後通過物件的match、search、findall方法完成匹配

正則規則

  • 單個字元:

    普通字元:簡單來說就是一對一的完全匹配
    []:中間的任意一個字元
        [a-z]:a~z之間的字元(所有小寫字母)
        [0-9]:0~9之間的字元(所有數字)
        [A-Z0-9]:所有的大寫字母和數字
        [^abc]:除abc外的所有字元
    . :匹配'\n'以外的任意字元
    \d:所有的數字,等價於[0-9]
    \D:所有的非數字,等價於[^0-9]
    \w:所有的數字、字母(中文)、下劃線等(就是字)
    \W:所有的非字字元(\w的取反)
    \s:所有的空白字元(\n、\t、\t、空格等)
    \S:所有的非空白字元
    \b:詞邊界匹配(開頭、結尾、標點、空格)
    \B:非詞邊界匹配
  • 次數控制

    *:前面的字元出現任意次
    +:前面的字元出現至少一次
    ?:前面的字元出現至多一次
    {m}:指定次數,m表示出現的次數
    {m,}:至少指定次數
    {m,n}:指定範圍內的次數,m到n次之間
    {,n}:至多n次,相當於{0,n}

    正則的匹配預設都是貪婪的(最大限度的匹配)

  • 邊界限定

    • ^:以指定的內容開頭
    • $:以指定的內容結尾
    • 示例
    import re
    
    # 以指定的內容開頭
    # c = re.compile(r'^abc')
    # 以指定的內容結尾
    c = re.compile(r'kas$')
    
    s = c.search('abcsdhkas')
    
    if s:
        print(s.group())
  • 優先順序控制

    • |:表示或,它擁有最低的優先順序
    • ():用於表示一個整體,明確的指定優先順序
    • 示例:
    import re
    
    c = re.compile(r'a(hello|world)b')
    
    s = c.search('aworldb')
    
    if s:
        print(s.group())
  • 分組匹配

    • 說明:()不但可以作為一個整體,還可以進行分組匹配
    • 示例1:
    import re
    
    c = re.compile(r'(\d+)([a-z]+)(\d+)')
    
    s = c.search('shd327sjahdajhsd87892ehawksd')
    
    if s:
        print(s.group())
        # 預設就是全部的匹配內容,等價於上式
        print(s.group(0))
        # 第一個()匹配到的內容
        print(s.group(1))
        print(s.group(2))
        print(s.group(3))
        print(s.span())
        print(s.span(0))
        print(s.span(1))
        print(s.span(2))
        print(s.span(3))
    • 示例2:給分組起名字
    import re
    
    # 固定匹配
    # c = re.compile(r'<div><a>\w+</a></div>')
    # \1表示前面第一個小括號匹配的內容
    # c = re.compile(r'<([a-z]+)><([a-z]+)>\w+</\2></\1>')
    # 給()起名字
    c = re.compile(r'<(?P<goudan>[a-z]+)><(?P<ergou>[a-z]+)>\w+</(?P=ergou)></(?P=goudan)>')
    
    s = c.search('<div><a>百度一下</a></div>')
    
    if s:
        print(s.group())
  • 貪婪匹配

    • 貪婪:最大限度的匹配叫貪婪。正則的匹配預設是貪婪。
    • 非貪婪:只要滿足匹配條件,能少匹配就少匹配;通過可以使用'?'進行取消貪婪
    • 示例:
    import re
    
    # 取消任意多次的貪婪
    # c = re.compile(r'a.*?b')
    # 取消至少一次的貪婪
    c = re.compile(r'a.+?b')
    
    s = c.search('abdhsadjbsdjabs')
    
    if s:
        print(s.group())
  • 匹配模式

    • 說明:所謂模式就是對匹配的原則進行整體的修飾
    • 示例:
    import re
    
    # 忽略大小寫的匹配
    # c = re.compile(r'hello', re.I)
    # s = c.search('Hello world')
    
    # 進行多行匹配,預設單行匹配
    # c = re.compile(r'^hello', re.M)
    # s = c.search('world \nhello')
    
    # 做為單行處理 或 讓 . 能夠匹配 \n
    c = re.compile(r'<div>.*?</div>', re.S)
    # string = '<div>hello</div>'
    string = '''<div>
    hello
    </div>'''
    s = c.search(string)
    
    if s:
        print(s.group())
  • 字元轉義

    • 若匹配正則語法中的特定字元都需要進行轉義
    • 正則字串會被處理兩次,python中處理一次,re模組會在處理一次
    • 若不想考慮字元的轉義問題,可以在書寫正則字串時前面加一個字元'r'
    • 新增'r'之後,在python不會再進行任何轉義,只需在與正則語法相關的字元前加''即可讓其使用原有意義