從基礎(chǔ)到進階詳解Python如何使用正則替換字符串
在Python中,字符串替換是常見的操作,但簡單的str.replace()方法只能處理固定字符串的替換。當(dāng)需要模式匹配(如替換所有數(shù)字、郵箱、URL等)時,正則表達式(re模塊)的re.sub()方法就派上了用場。本文將詳細介紹如何使用正則表達式進行字符串替換,并提供實際案例。
1. 基礎(chǔ)正則替換:re.sub()
1.1re.sub()基本語法
re.sub() 是Python正則替換的核心方法,語法如下:
import re re.sub(pattern, repl, string, count=0, flags=0)
pattern:正則表達式模式(匹配要替換的內(nèi)容)。repl:替換內(nèi)容(可以是字符串或函數(shù))。string:待替換的原始字符串。count:最大替換次數(shù)(默認0表示全部替換)。flags:正則標(biāo)志(如re.IGNORECASE忽略大小寫)。
1.2 簡單替換示例
(1) 替換所有數(shù)字
import re text = "我的電話是123456789,QQ是987654321" new_text = re.sub(r'\d+', '***', text) # \d+ 匹配1個或多個數(shù)字 print(new_text) # 輸出: 我的電話是***,QQ是***
(2) 替換所有非字母字符
text = "Hello! 123 @World#Python" new_text = re.sub(r'[^a-zA-Z]', ' ', text) # [^a-zA-Z] 匹配非字母字符 print(new_text) # 輸出: Hello World Python
(3) 忽略大小寫替換
text = "Python is FUN, python is powerful" new_text = re.sub(r'python', 'Java', text, flags=re.IGNORECASE) # 忽略大小寫 print(new_text) # 輸出: Java is FUN, Java is powerful
2. 高級替換技巧
2.1 使用分組(())和反向引用(\1,\2)
正則表達式可以用()分組,并在替換時用\1、\2引用分組內(nèi)容。
示例:交換日期格式(YYYY-MM-DD → DD/MM/YYYY)
text = "2023-01-01, 2024-12-31"
new_text = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\3/\2/\1', text) # \3=日, \2=月, \1=年
print(new_text)
# 輸出: 01/01/2023, 31/12/2024
2.2 使用函數(shù)動態(tài)替換
repl參數(shù)可以是一個函數(shù),根據(jù)匹配內(nèi)容動態(tài)生成替換字符串。
示例:將數(shù)字乘以2后替換
def double_num(match):
num = int(match.group()) # 獲取匹配的數(shù)字
return str(num * 2)
text = "1 apple, 2 bananas, 3 oranges"
new_text = re.sub(r'\d+', double_num, text) # 調(diào)用函數(shù)替換
print(new_text)
# 輸出: 2 apple, 4 bananas, 6 oranges
示例:隱藏敏感信息(如郵箱)
def hide_email(match):
email = match.group()
return email[0] + "***" + email[-4:] # 保留首字母和后4位
text = "聯(lián)系我:test@example.com 或 admin@site.org"
new_text = re.sub(r'[\w.-]+@[\w.-]+', hide_email, text)
print(new_text)
# 輸出: 聯(lián)系我:t***mple.com 或 a***site.org
2.3 限制替換次數(shù)(count參數(shù))
text = "111-222-333-444" new_text = re.sub(r'\d+', 'X', text, count=2) # 只替換前2個數(shù)字 print(new_text) # 輸出: X-X-333-444
3. 實際應(yīng)用案例
案例1:清理HTML標(biāo)簽
import re html = "<p>Hello, <b>World</b>!</p>" clean_text = re.sub(r'<[^>]+>', '', html) # 匹配所有HTML標(biāo)簽并刪除 print(clean_text) # 輸出: Hello, World!
案例2:標(biāo)準(zhǔn)化電話號碼格式
text = "電話:010-12345678,手機:138-1234-5678"
new_text = re.sub(r'(\d{3})-(\d{4})-(\d{4})', r'\1\2\3', text) # 嘗試直接替換(可能不匹配)
# 更通用的方法:
def normalize_phone(match):
full_num = re.sub(r'[^\d]', '', match.group()) # 先刪除所有非數(shù)字
if len(full_num) == 11: # 手機號碼
return f"手機:{full_num[:3]}-{full_num[3:7]}-{full_num[7:]}"
elif len(full_num) == 8: # 座機號碼(簡化版)
return f"電話:{full_num[:3]}-{full_num[3:]}"
else:
return match.group()
# 先提取所有電話號碼(簡化版,實際需更復(fù)雜正則)
text_with_phones = re.sub(r'(\d{3}[-]?\d{4}[-]?\d{4})|(\d{3}[-]?\d{4})', normalize_phone, text)
# 更準(zhǔn)確的方式是分兩步:
# 1. 提取所有電話號碼
# 2. 替換
print(text_with_phones) # 輸出可能不符合預(yù)期,需更精細的正則
# 更合理的實現(xiàn)(分兩步):
phones = re.findall(r'\d{3}[-]?\d{4}[-]?\d{4}|\d{3}[-]?\d{4}', text)
for phone in phones:
cleaned = re.sub(r'[^\d]', '', phone)
if len(cleaned) == 11:
new_phone = f"{cleaned[:3]}-{cleaned[3:7]}-{cleaned[7:]}"
elif len(cleaned) == 8:
new_phone = f"{cleaned[:3]}-{cleaned[3:]}"
else:
new_phone = phone
text = text.replace(phone, new_phone)
print(text)
# 輸出: 電話:010-12345678,手機:138-1234-5678
更簡潔的電話號碼標(biāo)準(zhǔn)化(使用re.sub直接替換):
text = "電話:010-12345678,手機:138-1234-5678"
def normalize_phone(match):
num = re.sub(r'[^\d]', '', match.group())
if len(num) == 11:
return f"手機:{num[:3]}-{num[3:7]}-{num[7:]}"
elif len(num) == 8:
return f"電話:{num[:3]}-{num[3:]}"
else:
return match.group()
# 匹配手機號(11位)或座機號(8位,可能帶-)
new_text = re.sub(
r'(手機:)?(\d{3}[-]?\d{4}[-]?\d{4})|(電話:)?(\d{3}[-]?\d{4})',
lambda m: normalize_phone(m),
text
)
# 上述正則不夠完美,更準(zhǔn)確的方式:
# 先提取所有電話號碼,再替換
print(new_text) # 可能需要調(diào)整正則
# 更準(zhǔn)確的實現(xiàn)(分兩步):
import re
text = "電話:010-12345678,手機:138-1234-5678"
# 匹配手機號或座機號
pattern = r'(?:電話:|手機:)?(\d{3}[-]?\d{4}[-]?\d{4}|\d{3}[-]?\d{4})'
def replace_phone(match):
raw_phone = match.group(1)
cleaned = re.sub(r'[^\d]', '', raw_phone)
if len(cleaned) == 11:
return f"手機:{cleaned[:3]}-{cleaned[3:7]}-{cleaned[7:]}"
elif len(cleaned) == 8:
return f"電話:{cleaned[:3]}-{cleaned[3:]}"
else:
return raw_phone
new_text = re.sub(pattern, replace_phone, text)
print(new_text)
# 輸出: 電話:010-12345678,手機:138-1234-5678
簡化版(假設(shè)輸入格式較規(guī)范):
text = "電話:010-12345678,手機:138-1234-5678"
new_text = re.sub(
r'(\d{3})-(\d{4})-(\d{4})', # 匹配手機號格式
r'手機:\1-\2-\3',
re.sub(
r'(\d{3})-(\d{4})', # 匹配座機號格式
r'電話:\1-\2',
text
)
)
print(new_text)
# 輸出: 電話:010-12345678,手機:138-1234-5678
案例3:替換URL中的協(xié)議(http → https)
text = "訪問 http://example.com 或 https://test.org" new_text = re.sub(r'http://', 'https://', text) # 簡單替換 print(new_text) # 輸出: 訪問 https://example.com 或 https://test.org
4. 常見問題與解決方案
問題1:正則表達式匹配不到內(nèi)容?
- 原因:正則模式錯誤或未使用
re.IGNORECASE等標(biāo)志。 - 解決:使用在線正則測試工具(如regex101.com)調(diào)試。
問題2:替換后格式混亂?
- 原因:未正確使用分組或反向引用。
- 解決:檢查
()分組和\1、\2是否匹配。
問題3:性能問題(大量文本替換)?
- 原因:
re.sub()在循環(huán)中調(diào)用或正則復(fù)雜度高。 - 解決:預(yù)編譯正則(
re.compile())或優(yōu)化正則表達式。
5. 總結(jié)
| 方法 | 適用場景 | 示例 |
|---|---|---|
| re.sub(r'\d+', 'X', text) | 簡單模式替換 | 替換所有數(shù)字為X |
| re.sub(r'(\d{4})-(\d{2})', r'\2/\1', text) | 分組與反向引用 | 交換日期格式 |
| re.sub(r'\d+', lambda m: str(int(m.group())*2), text) | 函數(shù)動態(tài)替換 | 數(shù)字乘以2后替換 |
| re.sub(r'<[^>]+>', '', text) | 清理HTML標(biāo)簽 | 刪除所有<...>標(biāo)簽 |
最佳實踐
- 簡單替換用
str.replace(),復(fù)雜模式用re.sub()。 - 需要保留部分匹配內(nèi)容時,用
()分組和\1反向引用。 - 動態(tài)生成替換內(nèi)容時,用函數(shù)作為
repl參數(shù)。 - 處理大量文本時,預(yù)編譯正則(
re.compile())提高性能。
掌握這些技巧后,你可以高效地處理各種字符串替換需求!
到此這篇關(guān)于從基礎(chǔ)到進階詳解Python如何使用正則替換字符串的文章就介紹到這了,更多相關(guān)Python正則替換字符串內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python數(shù)據(jù)類轉(zhuǎn)換為JSON的常用方法總結(jié)
這篇文章主要介紹了四種將Python自定義數(shù)據(jù)類實例轉(zhuǎn)換為JSON的優(yōu)雅方法,包括手動轉(zhuǎn)換、自定義JSONEncoder、封裝工具函數(shù)和使用pydantic,針對不同場景提供了詳細實現(xiàn)和解釋,需要的朋友可以參考下2026-01-01
python ceiling divide 除法向上取整(或小數(shù)向上取整)的實例
今天小編就為大家分享一篇python ceiling divide 除法向上取整 (或小數(shù)向上取整)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12
解鎖Python中神器vars內(nèi)置函數(shù)的使用
vars()函數(shù)是一個內(nèi)置函數(shù),用于返回對象的__字典__,其中包含對象的__屬性__,本文主要為大家詳細介紹了vars()函數(shù)的具體使用,需要的小伙伴可以了解下2023-11-11
講解Python的Scrapy爬蟲框架使用代理進行采集的方法
這篇文章主要介紹了講解Python的Scrapy爬蟲框架使用代理進行采集的方法,并介紹了隨機使用預(yù)先設(shè)好的user-agent來進行爬取的用法,需要的朋友可以參考下2016-02-02

