Python 正規表示式:權威指南

tags: python, regex, tutorial, programming


Python 正規表示式:權威指南

想像你正盯著一個 10,000 行的日誌檔,需要在數秒內提取出每一個電子郵件地址、IP 地址和時間戳。使用手動字串切割或巢狀迴圈來完成這件事不僅耗時,還很容易在邊緣案例上出錯。但有了 Python 正規表示式,你可以用一行簡潔的程式碼解決這個問題。正規表示式不僅是開發者的超能力,也是模式比對、文字驗證與資料提取的終極工具。讓我們一起掌握它。

開始使用 Python 的 re 模組

在撰寫複雜模式之前,你需要匯入正確的工具。Python 透過內建的 re 模組 來處理正規表示式。它輕量、強大,且在每一個標準 Python 安裝中都可使用。

import re

Enter fullscreen mode Exit fullscreen mode

開始時的黃金法則是:永遠使用原始字串來撰寫你的模式。在字串前加上 r 前綴(例如 r"\d+"),以防止 Python 在正規表示式引擎看到之前就把反斜線解讀為跳脫字元。這可以避免 \n 變成換行符而非字面上的「反斜線-n」模式這類細微的錯誤。

你每天會用到的核心正規表示式函式

re 模組提供了數個函式,但以下四個是你 90% 時間會用到的:

re.search()

掃描整個字串,若在任何位置找到符合模式的地方,便回傳一個 match 物件,否則回傳 None。它非常適合用來檢查某個條件是否存在。

re.match()

僅檢查模式是否在字串的最開頭就符合。若你的文字開頭有多餘空白或不相關字元,即使模式在後面存在,match() 也可能失敗。

re.findall()

回傳一個所有不重疊符合項目的清單。這是用來提取資料的首選,例如從文件中提取所有電話號碼。

re.sub()

搜尋模式的所有實例,並將它們替換為新字串。用於清理資料或清理輸入。

基本模式與特殊字元

正規表示式模式由普通字元(如 a5!)以及定義規則的元字元組成。以下是你今天就需要的基礎:

元字元 意義
. 任意單一字元(換行符除外)
^ 字串開頭
$ 字串結尾
\d 任意數字(0–9)
\w 任意文字字元(字母、數字或底線)
\s 任意空白字元(空格、定位點、換行符)

例如,r"\d{3}-\d{4}" 可以比對像 555-1234 這樣的美國電話號碼格式。

量詞:控制重複次數

你常常需要比對「一個或多個」或「零個或多個」字元。量詞可以處理這件事:

  • *:零個或多個(例如 ab* 比對 aababb
  • +:一個或多個(例如 ab+ 比對 ababb,但不比對 a
  • ?:零個或一個(例如 ab? 比對 aab
  • {n}:正好 n 次(例如 \d{4} 比對正好 4 個數字)
  • {n,m}:介於 nm 次之間

錨點與邊界

錨點讓你可以根據位置而非內容進行比對:

  • ^pattern:僅在模式位於開頭時比對。
  • pattern$:僅在模式位於結尾時比對。
  • \b:單詞邊界(可用來比對完整單詞,如 \bcat\b,以避免比對到「category」)。

實務範例

讓我們把所有東西整合起來。假設你有一個混亂的日誌字串,需要提取所有電子郵件地址、將它們替換為 [REDACTED],並計算找到的數量。

import re

log_text = """
User [email protected] logged in from 192.168.1.1.
Error: Invalid email user@@test.com. Contact [email protected].
Another user: [email protected] tried again.
"""

# 1. Define the email pattern
email_pattern = r"[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z]{2,}"

# 2. Find all emails
emails = re.findall(email_pattern, log_text)
print(f"Found {len(emails)} emails: {emails}")

# 3. Replace them
cleaned_log = re.sub(email_pattern, "[REDACTED]", log_text)
print("\nCleaned Log:")
print(cleaned_log)

Enter fullscreen mode Exit fullscreen mode

輸出:

Found 3 emails: ['[email protected]', '[email protected]', '[email protected]']

Cleaned Log:

User [REDACTED] logged in from 192.168.1.1.
Error: Invalid email user@@test.com. Contact [REDACTED].
Another user: [REDACTED] tried again.

Enter fullscreen mode Exit fullscreen mode

請注意 user@@test.com 因為違反模式(兩個 @ 符號)而被忽略。這就是精確正規表示式的威力:它會自動過濾雜訊

進階技巧:群組與前後查看

當你熟悉基礎之後,可以探索 群組 ( ) 來擷取比對結果的某部分。例如,r"(\d{4})-(\d{2})-(\d{2})" 可以將日期拆分成年、月、日。

前後查看(?=...)(正向先行斷言)讓你只在模式後面跟著另一個模式時才比對,且不將第二部分包含在結果中。這些對於複雜驗證非常強大,但若過度使用可能會降低效能。

效能提示與最佳實踐

正規表示式很快,但若撰寫不佳也可能變慢。以下是如何保持高效:

  • 編譯模式以重複使用:使用 pattern = re.compile(r"\d+"),然後 pattern.findall(text)
  • 由簡入繁:逐步建立你的模式,並用小輸入測試。
  • 不要過度使用正規表示式:若簡單的字串方法如 .split().replace() 就能運作,就使用它。正規表示式是用於複雜模式,而非所有字串任務。
  • 徹底測試:使用 regex101.com 等工具來視覺化比對結果並除錯邊緣案例。

重點摘要

  • 永遠使用原始字串r"pattern")以避免跳脫問題。
  • 掌握四個核心函式:search()match()findall()sub()
  • 使用量詞*+?{n})來控制重複。
  • 使用 ^$ 錨定模式以進行基於位置的比對。
  • 重複使用時編譯模式以提升效能。
  • 部署前用真實世界資料測試你的模式。

正規表示式是一項隨著練習而成長的技能。從今天解決一個小問題開始:驗證電子郵件、提取電話號碼,或清理 CSV 欄位。一旦你看到它如何將混亂的文字轉換為結構化資料,你就再也不會回到手動字串解析了。

準備好升級了嗎? 找一個混亂的文字檔,寫一個正規表示式模式來提取你需要的資料,並在 Dev.to 的留言區分享你的模式。讓我們一起建立正規表示式巫師社群吧!


如果您覺得這篇文章有幫助,歡迎請我喝杯咖啡 ☕——這能讓更多文章持續產出!

也歡迎看看我的 AI 工具集:AI 次元世界——開發者免費 AI 工具。