老夫的正規表示式大成了,桀桀桀桀!!!【Python 正規表示式筆記】

2023-05-12 21:01:11

一、正規表示式語法

(一) 字元與字元類

特殊字元

\.^$?+*{}[]()| 為特殊字元,若想要使用字面值,必須使用 \ 進行跳脫

字元類 []

[] 匹配包含在方括號中的任何字元。它也可以指定範圍,例:

  • [a-zA-Z0-9]表示a到z,A到Z,0到9之間的任何一個字元
  • [u4e00-u9fa5] 匹配 Unicode 中文
  • [^\x00-\xff] 匹配雙位元組字元(包括中文)

[] 中:

  • [^] 表示否定字元類,比如[^0-9]表示可以匹配一個任意非數位的字元
  • ^ 放在第一個位置表示否定,放在其他位置表示字面值
  • \ 表示跳脫
  • - 放在中間表示範圍,放在其他位置表示字面值
  • 其他特殊字元不再具備特殊意義,都表示字面值
  • 字元類內部可以使用速記法,比如\d \s \w

速記法

  • . 可以匹配除換行符之外的任何字元,如果有 re.DOTALL 標誌,則匹配任意字元包括換行
  • \d 匹配一個 Unicode 數位,如果有 re.ASCII 標誌,則匹配0-9
  • \D 匹配 Unicode 非數位
  • \s 匹配 Unicode 空白,如果帶有 re.ASCII 標誌,則匹配\t\n\r\f\v中的一個
  • \S 匹配 Unicode 非空白
  • \w 匹配 Unicode 單詞字元,如果帶有 re.ASCII 標誌,則匹配[a-zA-Z0-9_]中的一個
  • \W 匹配 Unicode 非單詞字元

(二)量詞

  • ? 0次或1次
  • * 0次或多次
  • + 1次或者多次
  • {m} m次
  • {m,} 至少m次
  • {,n} 最多n次
  • {m,n} 至少m次,最多n次

注意點:以上量詞都是「貪婪模式」,後加 ? 切換為「最小匹配模式」

(三) 斷言

斷言不會匹配任何文字,只是施加約束。常用斷言:

  • \b匹配單詞的邊界,放在字元類 [] 中則表示 backspace
  • \B匹配非單詞邊界,受ASCII標記影響
  • \A 在起始處匹配
  • \Z 在結尾處匹配
  • ^ 在起始處匹配,如果有 MULTILINE 標誌,則在每個換行符後匹配
  • $ 在結尾處匹配,如果有 MULTILINE 標誌,則在每個換行符前匹配

(四)捕獲組

()的作用:

  • ()是一個捕獲組,可被 \N 參照,N 是序號,以左括號排位決定。\0 表示整個匹配的內容。
  • (?:) 可以關閉捕獲,只用作分組
  • 使用 | 組合多個表示式,表示「或」
  • (?=...) 向前正項匹配,前方必須存在。 如\w+(?=,) 匹配 apple, banana 中的 apple
  • (?!...) 向前負項匹配,前方必須沒有
  • (?<=...) 向後正項匹配,後方必須存在
  • (?<!...) 向後負項匹配,後方必須沒有

命名捕獲組:

語言 命名捕獲組 搜尋中參照 替換中參照
Python (?P<name>...) \N (?P=name) \N \g<name> $N
JavaScript (?<name>...) \N \k<name> $N
.NET (?<name>...) (?'name'...) \N \k<name> \k'name' $N ${N} ${name}
Perl (?<name>...) (?'name'...) \N \gN \g{N} \g{name}
(?N) (?+N) (?-N) (?Name)
相容 .Net Python 的語法
$N ${N} $+{Name}

技巧:

  • 在搜尋中,若 \12 無法表示「第一個捕獲組 + 數位2」,可用 (?:\1)2 或者 \1[2] 表示
  • 在替換中,若 $12 無法表示「第一個捕獲組 + 數位2」,可以用 $1\l2 或者 $1\u2 表示

(五)條件匹配

  • (?(id)yes_exp|no_exp):對應 id 的子表示式如果匹配到內容,則這裡匹配 yes_exp,否則匹配 no_exp
  • Perl 支援的語法:(?(N)Yes|No) (?(<Name>)Yes|No) (?('Name')Yes|No) (?(?=Ahead)Yes|No)

實測 JavaScript 不支援條件匹配

(六)替換語法補充

一些在替換中使用的語法:

替換語法 作用
\l 下一個字元輸出小寫
\L 下一串字元輸出小寫
\u 下一個字元輸出大寫
\U 下一串字元輸出大寫
\E 終止 \U\L
語言 參照匹配之前的文字 參照匹配文字 參照匹配之後的文字
Perl ${^PREMATCH} | ${^MATCH} ${^POSTMATCH}

(七) 標誌

傳標誌方法:

  • 正規表示式開頭加標誌 (?flags)pattern ,如 (?im)apple 表示不區分大小寫
    • iIGNORECASE:忽略大小寫,使匹配不區分大小寫。
    • mMULTILINE:啟用多行模式
    • sDOTALL:啟用點字元(.)匹配任意字元,包括換行符。sspecial 的縮寫。
    • xVERBOSE:啟用詳細模式,忽略空格和註釋,可以使用多行形式編寫更易讀的正規表示式。可以用 [ ] \x20 (?-x: ) 表示空格。xextended 縮寫
    • gGLOBAL: 查詢所有符合條件的結果(Python 中不需要)
  • python 中 re.compile 的 flags 引數。flags 實質是一個數位,可以用 | 按位元與傳入多個標誌
    • re.Are.ASCII
    • re.Ire.IGNORECASE
    • re.Mre.MULTILINE
    • re.Sre.DOTALL
    • re.Xre.VERBOSE

註釋範例,匹配 <img> 標籤:

pattern = re.compile(r"""(?ix)          # i 表示忽略大小寫,x 表示開啟註釋模式
        <img\s+                         #標籤的開始
            [^>]*?                      #不是src的屬性
            src=                        #src屬性的開始
                (?P<quote>["'])         #左引號
                (?P<image_name>[^"'<>]+?)  #圖片名字
                (?P=quote)              #右括號
            [^>]*?                      #不是src的屬性
        >                               #標籤的結束
    """)

二、Python正規表示式模組

模組級 :

方法、屬性 作用
compile(pattern) 預先編譯正規表示式,返回 re.Pattern 物件
search(pattern, string, flags=0) 查詢匹配的部分,返回 re.Match
match(pattern, string, flags=0) 從頭匹配,返回符合規則的第一個值 re.Match
fullmatch(pattern, string, flags=0) 完全匹配(要從頭到尾都匹配),返回 re.Match
split(pattern, string, maxsplit=0) 用匹配到的內容作為分割符,分割後,返回列表
findall(pattern, string) 查詢所有,返回為列表,元素為 str。如果有捕獲組,則列表元素為 tuple,包含空結果。
finditer(pattern, string) 查詢所有,返回為 re.Match 的迭代器。
sub(pattern, repl, string, count=0) 返回替換後的字串,repl 可以是一個函數(接收 Match,返回替換後的值)
subn(pattern, repl, string, count=0) 返回元組 (new_str, number),包含了替換次數
escape(pattern) 將特殊字元跳脫後返回,如 . 會返回 \.
purge() 清除快取

re.compile() 可以預先編譯正規表示式,返回 re.Pattern 物件,以提高匹配效率

方法、屬性 作用
.search(string[, pos[, endpos]]) 查詢匹配的部分,返回 re.Matchposendpos 限制查詢區間
.match(string[, pos[, endpos]])
.fullmatch(string[, pos[, endpos]])
.split(string, maxsplit=0)
.findall()
.finditer()
.sub(repl, string, count=0)
.subn(repl, string, count=0)
.flags
.groups 有幾個捕獲組
.groupindex 一個字典,命名捕獲組與序號對應
.pattern

re.Match 物件用於表示正規表示式匹配的結果:

方法、屬性 作用
Match.group([group1, ...]) 返回:捕獲組,或多個捕獲組 tuple
Match[0] 等同於 group(0)
.group() 等同於 group(0)
.groups(default=None) 返回:元組,所有的子捕獲組 (1, 2, 3...)。沒有捕獲到的組返回為 None。
.groupdict(default=None) 返回:詞典,只包含有命名的捕獲組
.start() 返回:匹配的起始位置
.end() 返回:匹配的結束位置
.span() 返回:元組 (start, end)
.expand(template) 用捕獲到的組將 template 中的組參照展開
.pos 匹配開始的索引位置
.endpos 匹配結束的索引位置
.lastindex 最後一個捕獲組的索引
.lastgroup 最後一個捕獲組的名字
.string 傳入的字串