python中的正則表達式(簡要筆記)

應用場景

  • 特定規律字符串的查找替換切割等
  • 郵箱格式、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不會再進行任何轉義,只需在與正則語法相關的字符前加’'即可讓其使用原有意義
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章