正則表達式基礎用法整理

正則表達式

1. 正則表達式

1.1 正則表達式介紹

1.1.1 什麼是正則表達式?

  • 正則表達式就是一種字符串,該字符串經過包含特殊的符號,來描述一類字符串的公共特色,進而可使用該模式串來匹配並獲取文本內容中的全部符合該特色的字符串,也可使用該模式來對一些字符串進行匹配,觀察這些字符串是否符合該模式,實現字符串的篩選等功能,用途很是普遍

1.1.2 正則表達式的做用

  • 當咱們須要須要對字符串進行解析來獲取數據時,咱們能夠經過字符串定位(find)的方法,來尋找到本身所須要的信息或者縮減尋找信息的範圍,可是面對狀況複雜的字符串信息,可能須要設置多種條件來一一判斷;狀況越複雜,條件分支就會增加的極快,因此使用常規的字符串定位,而後進行判斷的方法顯然就不合適了;特別是在網絡爬蟲爬取的數據分析中,面對大量的字符數據要靠着本身來設置條件判斷顯然是很是困難的,因此咱們須要使用正則表達式來進行字符串的匹配,從而實現咱們想要的功能

1.2 正則表達式的使用

1.2.1 前提

(1)選用示例語言html

  • 爲了方便,本文使用python做爲正則表達式的使用示例,其實絕大部分主流語言都會支持正則表達式,使用過程也幾乎相同,只是不一樣語言有着不一樣的語法表示而已

(2)文本的獲取java

  • 使用requests庫來獲取B站首頁html頁面,將其寫入到文本中,避免每次測試都須要動用網絡資源python

    immport requests
    
    # 將html頁面寫入到文本
    with open("data.html","w",encoding="utf-8") as html:
        response = requests.get("https://www.bilibili.com/")
        html.write(response.text)
        
    # 讀取文本內容
    text = ''
    with open("data.html",'r',encoding="utf-8") as html:
        text = html.read()

(3)正則表達式的效果查看正則表達式

  • 學習過程當中可使用網站:regex101,來查看匹配效果:express

    • 上面爲正則表達式,下面爲文本內容,右側爲匹配的詳細信息

1.2.2 使用python匹配正則表達式

(1)re網絡

  • 導入re(regular expression)庫函數

    import re

(2)re.Pattern學習

  • 該類爲re庫中的一個類,經過傳入正則表達式構造該對象,用於去尋找匹配的字符串測試

    pattern = re.compile(r"正則表達式")
  • 一般使用 r"字符串"來表示這是一個原始字符串,即不對一些特殊字符,如"\","\t"等進行轉義,一下爲二者區別的示例:網站

    >>> str = "this is a string.\n \tand this is the second line."
    >>> print(str)
    this is a string.
            and this is the second line.
    >>> str = r"this is a string.\n \tand this is the second line."
    >>> print(str)
    this is a string.\n \tand this is the second line.

(3)pattern.finall(文本內容)

  • 該方法爲pattern對象的方法,用於依據正則表達式在匹配傳入文本中的全部內容,將符合規則的字符串存入列表中,最後返回該列表

    re.compile(r"嗶哩嗶哩")
    strList = patern.findall(text)
    print(strList)

    結果:

    <class 'list'>
    ['嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩 
    嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', 
    '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶
    哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩']

1.2.3 正則表達式中的特殊元字符

正則表達式的特殊字符包括:. * + ? \ [ ] ^ $ { } | ( )

(1)任意字符.

  • . 表示要匹配除了換行符以外的任何單個字符

    • 好比下面:

  • python示例:

    pattern = re.compile(r'.哩.哩')
    strList = pattern.findall(text)
    print(strList)

    結果:

    ['嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩 
    嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', 
    '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶
    哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩', '嗶哩嗶哩']
  • 能夠設置字符匹配模式爲DOTALL模式來使得.匹配換行符

    content = '''
    <div class="el">
            <p class="t1">           
                <span>
                    <a>Python開發工程師</a>
                </span>
            </p>
            <span class="t2">南京</span>
            <span class="t3">1.5-2萬/月</span>
    </div>
    <div class="el">
            <p class="t1">
                <span>
                    <a>java開發工程師</a>
                </span>
    		</p>
            <span class="t2">蘇州</span>
            <span class="t3">1.5-2/月</span>
    </div>
    '''
    
    pattern = re.compile(r'class=\"t1\">.*?<a>(.*?)</a>', re.DOTALL)
    print(pattern.findall())
    [Python開發工程師, java開發工程師]

(2)任意個數字符*

  • *表示匹配前面子表達式任意次

    • 好比:

      • 該處*表示匹配前面"嗶哩"任意次,即尋找"嗶哩"+"哩"*n(n>=0)這種字符串
    • 再好比:

      • 該處.匹配任意字符,*匹配前面任意字符的任意重複字符串,故匹配的字符串爲全文
    • 再好比:

      • 該表達式表示匹配"番"+"組"*n (n>=0)這種形式的字符串

(2)存在或多個字符+

  • +表示匹配前面的子表達式1次或者屢次,不包括0次

    • 好比:

      • 該表達式表示匹配"番"+"組"*n (n>=1)這種形式的字符串

(3)非肯定字符是否存在?

  • ?表示匹配前面的子表達式0或1次

    • 好比:

(4)指定字符出現次數{m,n}

  • {m,n}表示匹配前面的子表達式m至n次,它會以最大匹配次數來進行匹配

  • {m,}表示匹配前面的子表達式至少m次,它會以最大匹配次數來進行匹配

  • {m}表示匹配前面的子表達式m次,它只會匹配m次,即時後面還有可匹配的

    • 好比:

    • 再好比:

    • 再好比:

(5)指定字符範圍[]

  • [abcd]表示該字符只要符合爲括號中的一項便可

  • [m-n]表示在m至n的範圍內都符合該規則

  • 特殊字符在[]中再也不表示其特殊含義,可是\依舊會有轉義做用

    • 好比:

  • 若是在方括號中使用^,表示匹配不是括號中的字符

    • 好比:

(6)開頭^

  • 表示匹配文本的起始位置

  • 若是是單行模式 ,表示匹配整個文本的開頭位置。

    • 好比:

      text = """PS E:\PythonStudy> python -u "e:\PythonStudy\regexp\reglearn.py"   
      ['Alice', 'Bob']
      PS E:\PythonStudy> python -u "e:\PythonStudy\regexp\reglearn.py"   
      ['Alice', 'Bob', '大衛']
      PS E:\PythonStudy> python -u "e:\PythonStudy\regexp\reglearn.py"   
      ['Alice', 'Bob']
      """
      pattern = re.compile(r'^P.*?>')
      strList = pattern.findall(text)
      print(strList)
      ['PS E:\\PythonStudy>']

    若是是多行模式 ,表示匹配文本每行的開頭位置

    • 好比:

      pattern = re.compile(r'^P.*>',re.MULTILINE)
      strList = pattern.findall(text)
      print(strList)
      ['PS E:\\PythonStudy>', 'PS E:\\PythonStudy>', 'PS E:\\PythonStudy>']
      • 經過傳入re.MUTILINE或者re.M構建pattern對象,實現多行匹配模式

(7)結尾$

  • 表示匹配文本的結束位置

  • 若是是單行模式,表示匹配整個文本的結尾位置

    • text = """Alice say : <== privateKey
      Bob say : ==> publicKey
      """
      pattern = re.compile(r'\S*$')
      strList = pattern.findall(text)
      print(strList)
      ['publicKey', '', '']
  • 若是是多行模式,表示匹配文本每行的結尾位置

    • pattern = re.compile(r'\S*$',re.M)
      strList = pattern.findall(text)
      print(strList)
      ['privateKey', '', 'publicKey', '', '']

(8)其中之一|

  • 表示匹配前者或者後者,必須符合其中一個標準

    • 好比

(9)轉義\

  • 對特殊字符進行轉義,用於將特殊字符看作普通字符,參與匹配過程

  • 匹配某種字符類型:

    模式 含義
    \w 匹配數字字母下劃線等價於[ a-zA-Z0-9 ],缺省狀況下也包括Unicode文字字符,能夠指定爲只包括Ascll字符
    \W 匹配非數字字母下劃線,等價於[ ^a-zA-Z0-9 ]
    \s 匹配任意空白字符,等價於 [ \t\n\r\f ](tab,換行,空格)
    \S 匹配任意非空字符,等價於[ ^\t\n\r\f]
    \d 匹配任意數字,等價於 [0-9]。
    \D 匹配任意非數字,等價於[ ^0-9 ]
    \A 匹配字符串開始
    \Z 匹配字符串結束,若是是存在換行,只匹配到換行前的結束字符串。
    \z 匹配字符串結束
    \G 匹配最後匹配完成的位置。
    \b 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 能夠匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
    \B 匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
    \n, \t, \f,\v 匹配一個換行符,等價於 \x0a 和 \cJ;匹配一個製表符, 等價於 \x09 和 \cI;等;匹配一個換頁符,等價於 \x0c 和 \cL;匹配一個垂直製表符。等價於 \x0b 和 \cK
    \num 匹配 num,其中 num 是一個正整數。對所獲取的匹配的引用。例如,'(.)\1' 匹配兩個連續的相同字符

菜鳥教程

  • 對於\w,若是不指定風格,則會包含unicode編碼字符

    • 好比:

      text = """
      Alice
      Bob
      大衛
      """
      pattern = re.compile(r'\w{2,5}')
      strList = pattern.findall(text)
      print(strList)//['Alice', 'Bob', '大衛']
    • 可使用指定方式re.A,或則re.ASCII指定匹配模式爲字符只包含ascii碼的字符

      pattern = re.compile(r'\w{2,5}',re.A)
      strList = pattern.findall(text)
      print(strList)//['Alice', 'Bob']

1.2.4 分組

(1)分組介紹

  • 當經過正則表達式尋找匹配字符串時,能夠經過加入()的方式來對結果進行分組,從而獲取匹配字符串中的有效信息

(2)分組的使用

  • python代碼示例:

    text = """
    2020-4-13 22:04:27 Alice : hello,world.
    2020-4-13 22:04:32 Bob : nice to meet you.
    """
    # 使用分組
    pattern = re.compile(r'(\w*)\s:\s(.*).',re.M)
    strList = pattern.findall(text)
    print(strList)
    
    # 不使用分組
    pattern = re.compile(r'\w*\s:\s.*.',re.M)
    strList = pattern.findall(text)
    print(strList)

    結果:

    [('Alice', 'hello,world'), ('Bob', 'nice to meet you')]
    ['Alice : hello,world.', 'Bob : nice to meet you.']
  • 經過使用()將所須要的信息分離出來,最終會以元素爲元組的列表做爲返回結果

1.2.5 貪婪模式與非貪婪模式

(1)貪婪模式

  • 貪婪模式是指在匹配時會盡量的多匹配,當匹配的字符串已經符合要求時,若是後面的字符串依舊符合要求,則會繼續進行匹配,知道後面的字符串不符合規則

    • 好比:

      • 在尋找""pic":xxxxx.jpg"時,即時到第3行就已經匹配完成了,在該模式下,依舊會進行匹配,直至找到最後一個.jpg
  • +*都爲貪婪模式,會盡量地去匹配

(2)非貪婪模式

  • 該模式匹配到第一個符合表達式規則的字符串就會中止

  • 經過在+*{}後面加上?來使之以非貪婪模式匹配,只要知足第一次符合規則的狀況就能夠

    • 好比:

      • 在尋找到第一個符合表達式就中止,輸出匹配字符串,再繼續檢測
    • 再好比:

      • 原本結果應該是111,111,1,加入?以後只要有一個1即符合表達式,因此結果爲1,1,1,1,1,1,1

1.3 python正則表達式使用

1.3.1 re函數

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

  • 該方法只匹配字符串的開始,若是字符串開始不符合正則表達式,則匹配失敗,函數返回 None;若是匹配成功返回match對象

  • 經過group方法來得到結果

    text = """http:www.pics.com/cat.jpg
    http:www.imgs.com/dog.png
    http:www.imgs.com/doge.png
    http:www.pics.com/bird.gif
    http:www.pics.com/horse.jpeg
    """
    
    pattern = 'http.*\.(.*)\.com.*(\S*\.\S*)'
    print(re.match(pattern, text).group(0)) 
    print(re.match(pattern, text).group(1))  
    print(re.match(pattern, text).group(2)) 
    print(re.match(pattern, text).group()) 
    
    http:www.pics.com/cat.jpg
    pics
    .jpg
    http:www.pics.com/cat.jpg

(2)re.search(pattern, string, flags=0)

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

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

  • re.sub用於替換字符串中的匹配項

    • repl : 替換的字符串,也可爲一個函數
    • count : 模式匹配後替換的最大次數,默認 0 表示替換全部的匹配
  • 該方法返回一個新的被替換的字符串,源字符串不受影響

  • 示例:

    print(re.sub(pattern,"哈哈",text))
    哈哈:www.pics.com/cat.jpg
    哈哈:www.imgs.com/dog.png
    哈哈:www.imgs.com/doge.png
    哈哈:www.pics.com/bird.gif
    哈哈:www.pics.com/horse.jpeg

(4)re.compile(pattern[, flags])

  • compile 函數用於編譯正則表達式,生成一個正則表達式( Pattern )對象,提供match()和search() 這兩個函數使用

  • Pattern對象擁有re中的函數方法,即re.函數的Pattern參數爲自己

  • 例:

    pattern = re.compile(r'pics.*/(\S+).*')
    
    print(re.sub(pattern,"哈哈",text))
    print(pattern.sub("哈哈",text)) # 二者效果相同
  • python源碼:

    # 這是re.search方法,其它相似
    def search(pattern, string, flags=0):
        """Scan through string looking for a match to the pattern, returning
        a Match object, or None if no match was found."""
        return _compile(pattern, flags).search(string)
    • re.中的匹配函數所有爲套娃方法,即先構造Pattern對象,再利用該對象的方法完成其功能

(5)re.findall(string[, pos[, endpos]])

  • 在字符串中找到正則表達式所匹配的全部子串,並返回一個列表,若是沒有找到匹配的,則返回空列表

(6)re.finditer(pattern, string, flags=0)

  • 和 findall 相似,在字符串中找到正則表達式所匹配的全部子串的match對象,並把它們做爲一個迭代器返回

  • 示例

    pattern = re.compile(r'pics.*/(\S+).*')
    for match in pattern.finditer(text):
        print(match.group(1))
        
    cat.jpg
    bird.gif
    horse.jpeg

(7)re.split(pattern, string[, maxsplit=0, flags=0])

  • split 方法按照可以匹配的子串將字符串分割後返回列表,它的使用形式以下

    pattern = re.compile(r'/')
    print(pattern.split(text))
    
    ['http:www.pics.com', 'cat.jpg\nhttp:www.imgs.com', 'dog.png\nhttp:www.imgs.com', 'doge.png\nhttp:www.pics.com', 'bird.gif\nhttp:www.pics.com', 'horse.jpeg\n']

1.3.2 python中的匹配模式

(1)python中的正則表達式匹配模式

  • 源碼

    class RegexFlag(enum.IntFlag):
        ASCII = sre_compile.SRE_FLAG_ASCII # assume ascii "locale"          指定字符集爲ascii碼
        IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case          忽略大小寫
        LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale  
        UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode "locale"   根據Unicode字符集解析字符。這個標誌影響 \w, \W, \b, \B
        MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline  多行匹配
        DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline 使 . 匹配包括換行在內的全部字符
        VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments 這個選項忽略規則表達式中的空白和註釋,並容許使用 ’#’ 來引導一個註釋。這樣可讓你把規則寫得更美觀些
        A = ASCII
        I = IGNORECASE
        L = LOCALE
        U = UNICODE
        M = MULTILINE
        S = DOTALL
        X = VERBOSE
        # sre extensions (experimental, don't rely on these)
        TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking
        T = TEMPLATE
        DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation
相關文章
相關標籤/搜索