Python正則替換終極指南:用re.sub玩轉字符串魔法
一、為什么re.sub是文本處理的瑞士軍刀?
在Python的re
模塊中,re.sub()
的周下載量突破5800萬次(2025年PyPI數據),它實現了:
- 📍 模式匹配替換
- 📍 動態內容生成
- 📍 批量文本清洗
- 📍 結構化數據轉換
二、基礎篇:5分鐘掌握核心用法
1. 函數原型剖析
re.sub(pattern, repl, string, count=0, flags=0)
pattern
:正則表達式模式(字符串或編譯后的模式對象)repl
:替換內容(字符串或回調函數)string
:原始輸入字符串count
:最大替換次數(0表示全部替換)flags
:匹配模式(如忽略大小寫re.IGNORECASE
)
2. 基礎替換示例
import re # 替換所有數字為*
text = "訂單號:AB2025 金額:1500元"
result = re.sub(r"\d", "*", text)
print(result) # 訂單號:AB**** 金額:****元 # 限制替換次數
text = "1-2-3-4-5"
result = re.sub(r"-", ":", text, count=2)
print(result) # 1:2:3-4-5
以下案例均要添加 import re
三、進階篇:解鎖三大高階技巧
1. 分組捕獲與反向引用
\1 代表匹配的第1項,\2代表匹配的第2項,以此類推
# 重組日期格式(YYYY/MM/DD → DD-MM-YYYY)
text = "2025/02/20 → 2026/03/21"
result = re.sub(r"(\d{4})/(\d{2})/(\d{2})", r"\3-\2-\1", text)
print(result) # 20-02-2025 → 21-03-2026 # 給手機號加掩碼
text = "聯系電話:13812345678"
result = re.sub(r"(\d{3})\d{4}(\d{4})", r"\1****\2", text)
print(result) # 聯系電話:138****5678
2. 動態回調函數
# 數學表達式升級(數字擴大1000倍)
def multiply(match):num = float(match.group(1))return str(num * 1000)text = "重量0.5kg 長度1.2m"
result = re.sub(r"(\d+\.?\d*)", multiply, text)
print(result) # 重量500.0kg 長度1200.0m
3. 命名分組與復雜替換
# 處理國際化日期格式
text = "Date: 02/20/2025 (MM/DD/YYYY)"
result = re.sub(r"(\d{2})/(\d{2})/(\d{4})",r"\3年\2月\1日",text
)
print(result) # Date: 2025年02月20日 (MM/DD/YYYY)
四、工業級最佳實踐
1. 性能優化方案
\b:匹配一個單詞邊界。
# 預編譯正則模式(處理百萬級文本時提速3倍)
pattern = re.compile(r"\b\d{6}\b") # 匹配6位純數字
text = "郵政編碼:100001 200002"
result = pattern.sub("[郵編]", text)
print(result) # 郵政編碼:[郵編] [郵編]
2. 處理多語言文本
中日韓字符過濾(2025年新增unicode擴展區支持)
# 預編譯正則表達式(工業級推薦)
cjk_pattern = re.compile(r"([\u4e00-\u9fff\u3400-\u4dbf]|" # 中文r"[\u3040-\u309F\u30A0-\u30FF]|" # 日文r"[\uAC00-\uD7A3\u1100-\u11FF])+", # 韓文flags=re.UNICODE
)text = "2025新版:漢字 かな ????"
result = cjk_pattern.sub("[CJK]", text)
print(result) # 輸出:2025[CJK]:[CJK] [CJK] [CJK]
如果不過濾中文:
cjk_pattern = re.compile(r"([\u3040-\u309F\u30A0-\u30FF]|" # 日文r"[\uAC00-\uD7A3\u1100-\u11FF])+", # 韓文flags=re.UNICODE
)text = "2025新版:漢字 かな ????"
result = cjk_pattern.sub("[CJK]", text)
print(result) # 2025新版:漢字 [CJK] [CJK]
3. 安全替換策略
# 防御正則注入攻擊
def safe_sub(pattern, repl, text):escaped_pattern = re.escape(pattern)return re.sub(escaped_pattern, repl, text)user_input = "惡意輸入[a-z].*"
text = "重要數據:abc123"
result = safe_sub(user_input, "", text) # 原樣輸出
print(result) # 重要數據:abc123
五、三大實戰應用場景
1. 數據清洗管道
def clean_log(text):rules = [(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", "[IP]"), # 隱藏IP (r"\d{2}:\d{2}:\d{2}", "[TIME]"), # 隱藏時間 (r"password=\w+", "password=") # 脫敏密碼 ]for pattern, repl in rules:text = re.sub(pattern, repl, text)return text
2. 模板引擎開發
template = "歡迎{name}!您的訂單{order_id}已發貨"
context = {"name": "張三", "order_id": "20250220"}def render(tpl, data):return re.sub(r"{(\w+)}",lambda m: str(data.get(m.group(1), "")), tpl )print(render(template, context)) # 歡迎張三!您的訂單20250220已發貨
3. Markdown轉換器
def markdown_to_html(text):text = re.sub(r"### (.+)", r"\1", text) # 三級標題 text = re.sub(r"!\[(.*?)\]\((.*?)\)", r'', text)return text