最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中正則表達式從入門到精通詳解(這一篇就夠了!)

 更新時間:2026年06月24日 10:42:51   作者:zzwq.  
正則表達式是每一位開發(fā)者必須掌握的文本處理利器,它能以簡潔語法高效完成復雜匹配任務,這篇文章主要介紹了Python中正則表達式從入門到精通的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

一、正則表達式是什么?

1.1 一個生活化的理解

想象一下,你在一個巨大的圖書館里,想找所有書名中包含Python的書。如果一本本翻,你可能要花上一整天。但如果你有一個魔法探測器,只要輸入Python這個關鍵詞,所有相關書籍就會自動跳出來——這就是正則表達式的工作原理!

正則表達式(Regular Expression,簡稱regex)是一種用于描述字符串模式的特殊語法。它使用一系列特殊字符和普通字符來定義一種模式,然后用這種模式去匹配、查找、替換或分割文本。簡單來說,正則表達式就是一套文本搜索的規(guī)則,告訴你想要找什么樣的字符串。

1.2 正則表達式能做什么?

正則表達式在文本處理領域可謂是全能選手,主要可以解決四類問題:

  • 校驗文本內容:驗證用戶輸入的手機號、郵箱格式是否正確
  • 提取文本內容:從一堆雜亂文本中抓取你想要的信息
  • 替換文本內容:批量修改文本中的某些模式
  • 切割文本內容:按照特定規(guī)則拆分字符串

比如,你可以在幾萬行日志中快速找到所有報錯的時間戳,或者將文檔中的所有日期格式從“2026/01/01”批量替換為“2026-01-01”。

1.3 開始前的準備

在Python中使用正則表達式,首先需要導入內置的re模塊:

import re

建議在編寫正則表達式時使用原生字符串(即在字符串前加r),這樣可以避免轉義字符帶來的麻煩:

python
# 推薦寫法
pattern = r'\d+'  # 匹配數(shù)字

# 不推薦(雖然也能用)
pattern = '\\d+'

二、正則表達式基礎語法

正則表達式的核心是一套“元字符”——這些字符在正則表達式中有著特殊含義,而不是代表它們本身的樣子。掌握下面這些常用語法,足以應對大多數(shù)日常使用場景。

2.1 元字符詳解

元字符含義示例匹配結果
.匹配除換行符以外的任意單個字符a.baab、a5b、a b
^匹配字符串開頭Hello以Hello開頭的字符串
$匹配字符串結尾world$以world結尾的字符串
*匹配前面的子表達式0次或多次ab*cac、abc、abbc
+匹配前面的子表達式1次或多次ab+cabc、abbc(不匹配ac)
?匹配前面的子表達式0次或1次colou?rcolor、colour
{n}匹配前面的子表達式恰好n次a{3}aaa
{n,m}匹配前面的子表達式至少n次,最多m次a{2,4}aa、aaa、aaaa
[ ]字符集合,匹配括號內任意一個字符[abc]a、b或c中的任意一個
[^]負值字符集合,匹配未包含的任意字符[^abc]除了a、b、c之外的任何字符
|或運算符cat\|dogcat或dog
()分組標記(ab)+ab、abab
\轉義字符\.匹配句點.本身

2.2 預定義字符集(簡化寫法)

正則提供了一些預定義的字符集,可以大大簡化表達式的書寫:

預定義字符等價寫法含義
\d[0-9]匹配任意數(shù)字
\D[^0-9]匹配任意非數(shù)字
\w[a-zA-Z0-9_]匹配字母、數(shù)字、下劃線
\W[^a-zA-Z0-9_]匹配非字母、數(shù)字、下劃線
\s[ \t\n\r\f\v]匹配任意空白字符(空格、制表符、換行等)
\S[^ \t\n\r\f\v]匹配任意非空白字符
\b    —單詞邊界(匹配單詞開頭或結尾)

舉個例子:

\d+ 表示匹配一個或多個連續(xù)的數(shù)字(比如提取文本中的所有數(shù)字)
\w+ 表示匹配一個或多個單詞字符(比如提取英文單詞)
\s+ 表示匹配一個或多個空白字符(比如用來分割字符串)

2.3 理解“貪婪”與“非貪婪”

貪婪匹配:默認情況下,正則表達式會盡可能多地匹配字符。比如正則<.*>匹配字符串<div>hello</div>時,會匹配整個<div>hello</div>,而不是只匹配<div>。

非貪婪匹配:在量詞后面加一個?,就會變成非貪婪模式,盡可能少地匹配字符。比如<.*?>只會匹配<div>。

python
import re

text = '<div>hello</div><p>world</p>'

# 貪婪匹配(默認)——匹配盡可能長的結果
print(re.findall(r'<.*>', text))
# 輸出: ['<div>hello</div><p>world</p>']

# 非貪婪匹配(加 ?)——匹配盡可能短的結果
print(re.findall(r'<.*?>', text))
# 輸出: ['<div>', '</div>', '<p>', '</p>']

非貪婪模式在處理HTML標簽、引號內的內容時非常有用。

三、re模塊常用函數(shù)

Python的re模塊提供了豐富的函數(shù)來處理正則表達式。

3.1 re.match()——從頭開始匹配

re.match()從字符串的起始位置開始匹配,如果開頭不符合規(guī)則就返回None。

python
import re

# match要求從開頭就匹配
result = re.match(r'\d+', '123abc456')
if result:
    print(result.group())  # 輸出: 123

# 開頭不匹配,返回None
result = re.match(r'\d+', 'abc123')
print(result)  # 輸出: None

3.2 re.search()——搜索第一個匹配

re.search()在整個字符串中搜索,返回第一個匹配到的結果。

python
import re

# search在整個字符串中查找
result = re.search(r'\d+', 'abc123def456')
if result:
    print(result.group())  # 輸出: 123(只返回第一個)

match()和search()的區(qū)別在于:match()必須從字符串開頭匹配,search()可以在任何位置查找。

3.3  re.findall()——找出所有匹配 (最常用)

re.findall()返回字符串中所有不重疊匹配項的列表,是日常使用最頻繁的函數(shù)。

python
import re

text = '我有3個蘋果,5個香蕉,8個橙子'
# 找出所有數(shù)字
numbers = re.findall(r'\d+', text)
print(numbers)  # 輸出: ['3', '5', '8']

# 找郵箱
text2 = '聯(lián)系我: test@example.com 或 support@python.org'
emails = re.findall(r'\w+@\w+\.\w+', text2)
print(emails)  # 輸出: ['test@example.com', 'support@python.org']

3.4 re.finditer()——逐個獲取匹配對象

當需要處理大量匹配結果時,finditer()返回一個迭代器,每個元素是Match對象,比findall()更節(jié)省內存。

python
import re

text = '價格: 100元, 200元, 300元'
for match in re.finditer(r'\d+', text):
    print(f'找到數(shù)字: {match.group()},位置: {match.span()}')
# 輸出:
# 找到數(shù)字: 100,位置: (4, 7)
# 找到數(shù)字: 200,位置: (9, 12)
# 找到數(shù)字: 300,位置: (14, 17)

3.5  re.sub()——替換文本

re.sub()用于替換字符串中匹配模式的部分,是批量處理文本的利器。

python
import re

# 將數(shù)字替換為 #
result = re.sub(r'\d+', '#', '房間123,樓層4')
print(result)  # 輸出: 房間#,樓層#

# 移除所有空白字符
text = 'abc 12\ de 23 \n f45 6'
cleaned = re.sub(r'\s+', '', text)
print(cleaned)  # 輸出: abc12de23f456

3.6  re.split()——按模式分割

re.split()按照匹配模式分割字符串,返回一個列表。

python
import re

# 按數(shù)字分割字符串
text = 'abc123def456ghi'
parts = re.split(r'\d+', text)
print(parts)  # 輸出: ['abc', 'def', 'ghi']

# 按多種分隔符分割
text2 = 'apple, banana; orange|grape'
result = re.split(r'[,;|]', text2)
print(result)  # 輸出: ['apple', ' banana', ' orange', 'grape']

3.7  re.compile()——編譯正則表達式

如果在程序中多次使用同一個正則表達式,可以將其編譯成一個Pattern對象,這樣可以提高效率。

python
import re

# 編譯正則表達式
pattern = re.compile(r'\d+')

# 然后就可以反復使用這個pattern對象了
text1 = '我有10個蘋果'
text2 = '他有20個橙子'

print(pattern.findall(text1))  # ['10']
print(pattern.search(text2).group())  # 20
print(pattern.sub('#', '價格123元'))  # 價格#元

四、分組與捕獲

4.1 基礎分組:用 () 提取關鍵內容

分組是正則表達式中最強大的功能之一。用圓括號將想要單獨獲取的部分括起來,匹配成功后就可以通過.group(1)、.group(2)等提取出來。

python
import re

# 提取電話號碼的區(qū)號和號碼
text = '我的電話是010-12345678'
pattern = r'(\d{3})-(\d{8})'

match = re.search(pattern, text)
if match:
    print(f'區(qū)號: {match.group(1)}')   # 輸出: 010
    print(f'號碼: {match.group(2)}')   # 輸出: 12345678
    print(f'完整匹配: {match.group(0)}') # 輸出: 010-12345678
    print(f'所有分組: {match.groups()}') # 輸出: ('010', '12345678')

4.2 非捕獲分組 (?:...)

有些時候我們只需要分組功能來應用量詞,但不需要提取這部分內容,這時可以使用非捕獲分組(?:...)。非捕獲分組不會占用分組編號,性能也更高。

python
import re

# 非捕獲分組:只分組不捕獲
pattern = r'(?:https?://)?(\w+\.\w+)'
text = '訪問 https://example.com 和 http://python.org'

matches = re.findall(pattern, text)
print(matches)  # 輸出: ['example.com', 'python.org']

4.3 命名分組 (?P<name>...)

當分組較多時,用數(shù)字編號group(1)、group(2)很容易搞混。命名分組可以給每個分組起一個名字,大大提升代碼的可讀性。

python
import re

# 命名分組:使用 (?P<名字>模式) 的格式
pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
text = '今天是2025-03-15'

match = re.search(pattern, text)
if match:
    print(f'年: {match.group("year")}')   # 輸出: 2025
    print(f'月: {match.group("month")}')  # 輸出: 03
    print(f'日: {match.group("day")}')    # 輸出: 15
    print(f'所有命名分組: {match.groupdict()}')
    # 輸出: {'year': '2025', 'month': '03', 'day': '15'}

4.4 反向引用 \1、\2 等

反向引用允許在同一個正則表達式中引用前面捕獲組的內容,常用于匹配重復的結構。

python
import re

# 匹配重復的單詞(如 "hello hello")
pattern = r'\b(\w+)\s+\1\b'
print(re.search(pattern, 'hello world'))    # 輸出: None(不匹配)
print(re.search(pattern, 'hello hello'))    # 輸出: 匹配成功
print(re.search(pattern, 'good good study')) # 輸出: 匹配成功(good good)

五、進階技巧

5.1 零寬斷言——精準定位的秘密武器

零寬斷言是一種不消耗字符的匹配方式,它只判斷位置是否符合條件,而不把判斷用的字符包含在匹配結果中。簡單來說,就是“我要求前面/后面有什么(或沒什么),但我不把它拿走”。

四種斷言類型:

斷言類型語法含義
正向先行斷言(?=...)匹配后面是指定內容的位置
負向先行斷言(?!...)匹配后面不是指定內容的位置
正向后行斷言(?<=...)匹配前面是指定內容的位置
負向后行斷言(?<!...)匹配前面不是指定內容的位置

實戰(zhàn)示例:

python
import re

# 示例1:提取美元符號后面的數(shù)字(正向后行斷言)
text = '售價¥299,促銷價$199'
pattern = r'(?<=\$)\d+'  # 匹配 $ 后面的數(shù)字,但 $ 不包含在結果中
print(re.findall(pattern, text))  # 輸出: ['199']

# 示例2:排除jpg/png文件(負向先行斷言)
files = 'image.jpg backup.zip config.yaml'
pattern = r'\b\w+\.(?!jpg|png)\w{3}\b'  # 匹配不是jpg/png結尾的文件
print(re.findall(pattern, files))  # 輸出: ['backup.zip', 'config.yaml']

# 示例3:提取中括號內的內容(前后配合)
log = 'ERROR [2026-01-01] 系統(tǒng)崩潰'
pattern = r'(?<=\[).+?(?=\])'  # 匹配 [ 和 ] 之間的內容
print(re.search(pattern, log).group())  # 輸出: 2026-01-01

5.2 貪婪與非貪婪再深入

前面我們簡單介紹了貪婪和非貪婪,這里再補充一些優(yōu)化建議:

  • 當匹配引號內的內容時,"(.+?)" 雖然能用,但每次遇到引號都要嘗試回溯。更好的寫法是 "([^"]*)",直接用否定字符集匹配到下一個引號,避免了回溯嘗試。
  • 在量詞后面加?即可變成非貪婪模式:*?、+?、{n,m}?、??。

5.3 性能優(yōu)化建議

如果處理的是大規(guī)模文本,正則表達式的性能就變得至關重要:

1. 預編譯正則表達式:對于重復使用的模式,使用re.compile()編譯成Pattern對象
2. 避免災難性回溯:不要使用(a+)+這類嵌套量詞,會導致指數(shù)級回溯
3. 用字符類替代點號:[^"]* 比 .*? 更高效
4. 使用錨點:^ 和 $ 能幫助正則引擎快速定位,減少搜索范圍
5. 先用簡單方法過濾:對于大規(guī)模文本,先用 in 操作符或 startswith() 粗略篩選,再用正則精確匹配。

六、實戰(zhàn)案例

6.1 提取中文字符

python
import re

text = 'Python正則表達式入門教程123'
# 匹配中文字符(基本漢字范圍)
chinese = re.findall(r'[\u4e00-\u9fff]+', text)
print(chinese)  # 輸出: ['正則表達式入門教程']

6.2 驗證手機號碼

python
import re

def is_valid_phone(phone):
    pattern = r'^1[3-9]\d{9}$'  # 11位數(shù)字,以1開頭,第二位是3-9
    return bool(re.match(pattern, phone))

print(is_valid_phone('13812345678'))  # True
print(is_valid_phone('12345678901'))  # False

6.3 提取郵箱地址

python
import re

text = '請聯(lián)系我: test.user@example.com 或 admin@python.org'
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
emails = re.findall(pattern, text)
print(emails)  # 輸出: ['test.user@example.com', 'admin@python.org']

6.4 數(shù)據清洗——去除HTML標簽

python
import re

html = '<div class="content"><p>歡迎來到<span>Python</span>世界!</p></div>'
# 去除所有HTML標簽
clean_text = re.sub(r'<[^>]+>', '', html)
print(clean_text)  # 輸出: 歡迎來到Python世界!

6.5 日志解析實戰(zhàn)

python
import re

log = '''
2026-04-06 19:23:45 INFO 用戶登錄成功
2026-04-06 19:25:12 ERROR 數(shù)據庫連接失敗
2026-04-06 19:30:08 WARN 響應時間過長
'''

# 提取所有錯誤日志的時間和信息
pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ERROR (.+)'
errors = re.findall(pattern, log)
for time, msg in errors:
    print(f'錯誤發(fā)生時間: {time}, 錯誤信息: {msg}')
# 輸出: 錯誤發(fā)生時間: 2026-04-06 19:25:12, 錯誤信息: 數(shù)據庫連接失敗

七、常見錯誤與避坑指南

錯誤1:忘記使用原生字符串

python
# 錯誤寫法
pattern = '\d+'  # 這里 \d 可能被Python解釋器當作轉義序列處理

# 正確寫法
pattern = r'\d+'  # 使用原生字符串

錯誤2:混淆 match 和 search

python
# re.match() 要求從開頭匹配
re.match(r'\d+', 'abc123')  # 返回 None

# re.search() 可以在任何位置查找
re.search(r'\d+', 'abc123')  # 返回匹配對象

錯誤3:分組編號理解錯誤

分組編號是按照左括號出現(xiàn)的順序來確定的,而不是按照層級。例如在((A)(B))C中,組1是((A)(B)),組2是(A),組3是(B)。

錯誤4:正則表達式寫得太復雜

正則表達式并非越復雜越好。如果模式極其復雜(比如完整匹配URL或郵箱的“完美”正則),建議用專門的庫來處理,而不是試圖用一個正則解決所有問題。保持簡潔和可維護性更重要。

總結

到此這篇關于Python中正則表達式從入門到精通的文章就介紹到這了,更多相關Python正則表達式詳解內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Python2手動安裝更新pip過程實例解析

    Python2手動安裝更新pip過程實例解析

    這篇文章主要介紹了Python2手動安裝更新pip過程實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07
  • PyInstaller的安裝和使用的詳細步驟

    PyInstaller的安裝和使用的詳細步驟

    這篇文章主要介紹了PyInstaller的安裝和使用的詳細步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • python openCV自制繪畫板

    python openCV自制繪畫板

    這篇文章主要為大家詳細介紹了python openCV自制繪畫板,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • windows下添加Python環(huán)境變量的方法匯總

    windows下添加Python環(huán)境變量的方法匯總

    默認情況下,在windows下安裝python之后,系統(tǒng)并不會自動添加相應的環(huán)境變量。此時不能在命令行直接使用python命令。今天我們就來看下,如何簡單快捷的在windows下添加Python環(huán)境變量
    2018-05-05
  • flask + pymysql操作Mysql數(shù)據庫的實例

    flask + pymysql操作Mysql數(shù)據庫的實例

    下面小編就為大家?guī)硪黄猣lask + pymysql操作Mysql數(shù)據庫的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Python的Flask框架的簡介和安裝方法

    Python的Flask框架的簡介和安裝方法

    這篇文章主要介紹了Python的Flask框架的簡介和安裝方法,Flask是一款高人氣的非常簡潔的web開發(fā)框架,需要的朋友可以參考下
    2015-11-11
  • Python利用Pydub實現(xiàn)自動分割音頻

    Python利用Pydub實現(xiàn)自動分割音頻

    pydub是一個輕量級的音頻處理庫,安裝方便,使用簡單。而且pydub提供了豐富的音頻處理功能,包括切割、合并、轉換等。本文將利用Pydub實現(xiàn)自動分割音頻功能,感興趣的可以了解一下
    2023-05-05
  • python之MSE、MAE、RMSE的使用

    python之MSE、MAE、RMSE的使用

    今天小編就為大家分享一篇python之MSE、MAE、RMSE的使用,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python數(shù)據類型探索列表魔法世界

    Python數(shù)據類型探索列表魔法世界

    這篇文章主要為大家介紹了Python數(shù)據類型探索列表魔法世界,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Python實現(xiàn)輸出某區(qū)間范圍內全部素數(shù)的方法

    Python實現(xiàn)輸出某區(qū)間范圍內全部素數(shù)的方法

    這篇文章主要介紹了Python實現(xiàn)輸出某區(qū)間范圍內全部素數(shù)的方法,涉及Python數(shù)值運算、排序、判斷等相關操作技巧,需要的朋友可以參考下
    2018-05-05

最新評論

吉林市| 马山县| 东乡| 武穴市| 澜沧| 曲沃县| 句容市| 武义县| 高平市| 澜沧| 屯门区| 阿克苏市| 抚州市| 滨州市| 芜湖县| 洪洞县| 平昌县| 宜春市| 东平县| 定西市| 比如县| 无为县| 博客| 仪陇县| 金寨县| 定西市| 泰来县| 南木林县| 和平县| 西宁市| 遂昌县| 丰原市| 建始县| 巫溪县| 灵寿县| 镇平县| 格尔木市| 颍上县| 丁青县| 改则县| 海伦市|