博客 / 詳情

返回

藍易雲cdn:python正則表達式小結

Python 正則表達式小結:把<span style="color:red;">文本處理</span>做成可複用的“規則引擎” ✅🙂

在工程裏(日誌解析、IP/域名提取、配置校驗、數據清洗),正則的價值不在“寫得炫”,而在於:把<span style="color:red;">規則固化</span>、可讀可測、可演進。核心原則就三條:先定邊界再定分組最後治理性能


1)核心語法速查表(最常用、最容易踩坑)📌

類別 寫法 含義 典型用途 風險點/建議
邊界 ^ / $ 行首/行尾 嚴格校驗 多行要配<span style="color:red;">MULTILINE</span>
字符類 \d \w \s 數字/單詞/空白 提取字段 受 Unicode 影響,必要時加 ASCII 策略
集合 [abc] / [^a] 任選/排除 白名單/黑名單 用集合代替多個 or
量詞 * + ? {m,n} 次數控制 匹配長度 默認<span style="color:red;">貪婪</span>
非貪婪 *? +? ?? {m,n}? 儘量少匹配 HTML/標籤內 仍需“邊界”約束
分組 ( ) / (?: ) 捕獲/不捕獲 提取字段 捕獲太多會讓維護成本飆升
命名組 (?P<name>...) 可讀字段 日誌解析 輸出結構更清晰
斷言 (?=) (?!) (?<=) (?<!) 只判斷不消費 前後綴條件 過度使用會傷性能
標誌 re.I re.M re.S re.X 忽略大小寫/多行/點匹配換行/可讀模式 可治理 把“行為”顯式化

2)API 選型:match/search/findall/finditer/sub(該用哪個)🚦

import re

pat = re.compile(r"\b\d{3,5}\b")  # 例:匹配 3~5 位數字(如狀態碼/端口)
text = "code=200 port=19090 retry=3"

print(pat.search(text).group())
print(pat.findall(text))

解釋:

  • re.compile(...):把正則編譯為對象,減少重複解析成本,適合“高頻規則”場景;這是<span style="color:red;">性能治理</span>的起點。
  • r"...":使用原始字符串,避免 \b \d 被 Python 字符串轉義吞掉;這屬於<span style="color:red;">可維護性</span>底線。
  • search():在全文任意位置找“第一個命中”;用於快速定位。
  • group():拿到命中的文本片段。
  • findall():拿到全部命中列表;適合統計與批量提取。

3)用<span style="color:red;">命名分組</span>把結果結構化(日誌解析更穩)🧩

import re

log_pat = re.compile(
    r"ip=(?P<ip>\d{1,3}(?:\.\d{1,3}){3})\s+status=(?P<status>\d{3})"
)

line = "ip=203.0.113.9 status=502 upstream=api"
m = log_pat.search(line)

print(m.group("ip"), m.group("status"))
print(m.groupdict())

解釋:

  • (?P<ip>...) / (?P<status>...):命名分組讓字段“自解釋”,比 group(1) 更適合團隊協作與長期運維。
  • (?:\.\d{1,3}){3}:用“非捕獲分組 + 次數”描述 IPv4 的 3 段重複結構,表達更緊湊。
  • groupdict():直接輸出字典,方便落庫、打點、做指標聚合。

4)用<span style="color:red;">斷言</span>做“條件匹配”(不吞字符,更像策略)🛡️

import re

# 只匹配以 "token=" 後面跟着的 8~32 位字母數字,但不把 "token=" 算進去
pat = re.compile(r"(?<=token=)[A-Za-z0-9]{8,32}")

s = "uid=1 token=Ab12Cd34EF56 scope=read"
print(pat.search(s).group())

解釋:

  • (?<=token=):後行斷言,要求前面必須是 token=,但斷言本身不佔用輸出,這讓“提取字段”更乾淨。
  • {8,32}:把長度邊界寫死,等於在做<span style="color:red;">輸入治理</span>,避免異常長串把匹配拖慢。

5)替換與清洗:sub 是“文本治理器”🧼🙂

import re

# 把連續空白壓縮為一個空格
s = "a\t\tb   c\n\n d"
print(re.sub(r"\s+", " ", s).strip())

解釋:

  • \s+:匹配任意連續空白(空格/製表/換行)。
  • sub(pattern, repl, text):把規則命中的片段替換為目標值;適合做規範化、脱敏、字段清洗。
  • strip():清理首尾空格,避免輸出“看起來差一點點”的髒數據。

思維導圖:從“能用”到“可運營”的正則路線圖(vditor/Markdown 可用)

mindmap
  root((Python 正則))
    語法
      邊界(^ $ \\b)
      字符類(\\d \\w \\s)
      量詞(* + ? {m,n})
      分組(捕獲/非捕獲/命名)
      斷言(前瞻/後顧)
    API
      compile
      search vs match vs fullmatch
      findall vs finditer
      sub split
    治理
      先定邊界
      少用貪婪
      規則可讀(re.X)
      高頻編譯複用
      單測覆蓋樣例

如果你告訴我你主要處理的文本類型(例如:訪問日誌、WAF 事件、DNS 解析記錄、配置文件),我可以把上面的“通用小結”直接落到一套<span style="color:red;">可複用規則庫</span>(含邊界、分組字段、異常樣例與測試用例),讓它從“技巧”升級成“資產”。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.