python正規表示式的貪婪匹配

2021-10-04 08:19:34 字數 3563 閱讀 6415

今天在工作過程中用到正規表示式。先說一下我的需求,給這樣乙個句子:

今天我和李白(li bai)一起去吃飯,路上碰到了露娜(luna),他倆打起來了。

我希望將句子中括號和括號裡的內容刪掉。這個需求可以通過 re.sub() 函式來實現。先介紹一下這個函式:

原型:rb.sub(pattern, repl, string, count=0, flags=0)

功能:將string**現的可以匹配pattern的內容用repl替換。count用來限制替換的子串數量。

現在我們來嘗試一下:

>>> import re

>>> s = '今天我和李白(li bai)一起去吃飯,路上碰到了露娜(luna),他倆打起來了。'

>>> re.sub("\(.*\)", "", s)

'今天我和李白,他倆打起來了。'

很明顯,結果和我們想要的不一樣,這就是因為正規表示式匹配預設是貪婪模式。什麼是貪婪模式?就是它的匹配結果會盡可能長,在例子中,我們的正規表示式 "\(.*\)" 目標是匹配以"("開頭")"結尾的子串,(li bai)和(li bai)一起去吃飯,路上碰到了露娜(luna)這兩個子串都符合要求,那麼它就會預設選擇長的,這就出現了我們剛才看到的結果。

可是我不想要這個結果,我想用非貪婪模式:讓左括號匹配到離它最近的右括號。很簡單,乙個 ? 就可以搞定!在"\(.*\)" 中,.*代表匹配任意長度的任意字元,我們在它後面加個?,再來試試看:

>>> import re

>>> s = '今天我和李白(li bai)一起去吃飯,路上碰到了露娜(luna),他倆打起來了。'

>>> re.sub("\(.*?\)", '', s)

'今天我和李白一起去吃飯,路上碰到了露娜,他倆打起來了。'

漂亮!這就是我們想要的結果。

非貪婪模式在什麼情況下奏效呢?我們用 'www.baidu.com' 再來試試,用re.match()函式來搜尋匹配子串,結果看起來會更直觀一些:

# 1.搜尋單個字元時無效

print("re.match('.', s): ", end='')

tmp = re.match('.', s).span()

print(s[tmp[0]:tmp[1]]) # re.match('.', s): w

print("re.match('.?', s): ", end='')

tmp = re.match('.?', s).span()

print(s[tmp[0]:tmp[1]]) # re.match('.?', s): w

# 2. 搜尋固定長度字串無效

print("re.match('.', s): ", end='')

tmp = re.match('.', s).span()

print(s[tmp[0]:tmp[1]]) # re.match('.', s): ww

print("re.match('.?', s): ", end='')

tmp = re.match('.?', s).span()

print(s[tmp[0]:tmp[1]]) # re.match('.?', s): ww

# 3. 搜尋限制長度的字串有效

print("re.match('.', s): ", end='')

tmp = re.match('.', s).span()

print(s[tmp[0]:tmp[1]]) # re.match('.', s): www.baid

print("re.match('.?', s): ", end='')

tmp = re.match('.?', s).span()

print(s[tmp[0]:tmp[1]]) # re.match('.?', s): www.b

# 4. 搜尋任意長度字串有效

# 5. 搜尋長度》=1的字串有效

# 6. 匹配某一字元0~1次

print("re.match('w?', s): ", end='')

tmp = re.match('w?', s).span()

print(s[tmp[0]:tmp[1]]) # re.match('w?', s): w

print("re.match('w??', s): ", end='')

tmp = re.match('w??', s).span()

print(s[tmp[0]:tmp[1]]) # re.match('w??', s):綜上所述,在以下幾種情況下非貪婪匹配可以發揮出它的作用:

*?: 匹配0到任意多個字元;

+?: 匹配乙個到任意多個字元;

?: 最少匹配m個,最多匹配n個字元;

??: 匹配0~1個;

總結:

python的正規表示式匹配時預設是貪婪模式的,貪婪模式下會匹配到符合正規表示式的最長的字串;如果想用非貪婪模式,加個?

推薦乙個正規表示式學習**:

python正規表示式 貪婪 非貪婪

主要就是.與.的區別,是貪婪的,是非貪婪的例子如下 import re line cats are smarter than dogs matchobj1 re.match r are line matchobj2 re.match r are line matchobj1.group 1 matc...

正規表示式貪婪模式

貪婪匹配與非貪婪匹配 貪婪匹配 預設情況下,正規表示式使用最長匹配原則 也叫貪婪匹配原則 例如 要將 zoom 中匹配 zo?的部 分替換成 r 替換的的結果是 rom 如果要將 zoom 中匹配 zo 的部分替換成 r 替換後的結果是 rm 非貪婪匹配 當字元?緊隨其他限定符 之後時,匹配模式變成...

正規表示式貪婪匹配

個人感覺對正規表示式理解的還算多的,貪婪模式也用過,但是最近匹配位址資訊的時候老是出錯 如下 寧波 鄞州 21.59901313997095 29.80867802546617 寧波鄞州區鄞縣大道萬科桂語裡小區 盲點小區 編號 fg 2019 寧波 鄞州 21.59901313997095 29.8...