2009-10-16 67 views
3

據我所知,如何使用?和?:和:在REGEX for Python?

* = "zero or more" 
? = "zero or more" ...what's the difference? 

而且,:< <我的書使用此,它說,它是「微妙」,但我不知道究竟這些幹什麼!

+0

您似乎無法找到任何**教程。你需要搜索引擎的幫助嗎? – SilentGhost 2009-10-16 09:58:28

回答

5

正如Manu所說的,?的意思是「零次或一次」。它與{0,1}相同。

而通過?:,你可能意思是(?:X),其中X是其他字符串。這被稱爲「非捕獲組」。 通常,當您圍繞某物包圍括號時,您會將這些括號匹配的內容進行分組。例如,正則表達式.(.).(.)與任意4個字符(換行符除外)匹配,並將第二個字符存儲在組1中,並將第四個字符存儲在組2中。但是,當您執行以下操作時:.(?:.).(.)只有第四個字符存儲在組1中, (?:.)匹配,但不是「記住」。

小演示:

import re 
m = re.search('.(.).(.)', '1234') 
print m.group(1) 
print m.group(2) 
# output: 
# 2 
# 4 

m = re.search('.(?:.).(.)', '1234') 
print m.group(1) 
# output: 
# 4 

你可能會問自己:「爲什麼在所有使用非捕獲組?」。那麼,有時候,你想在兩個字符串之間做一個OR,例如,你想匹配字符串「www.google.com」或「www.yahoo.com」,那麼你可以這樣做:www\.google\.com|www\.yahoo\.com,但更短會是:當然是www\.(google|yahoo)\.com。但是,如果您不打算對此組(谷歌搜索字符串或「雅虎」)捕獲的內容進行操作,那麼您還可以使用非捕獲組:www\.(?:google|yahoo)\.com。當正則表達式引擎不需要「記住」子字符串「谷歌」或「雅虎」,那麼你的應用程序/腳本將運行得更快。當然,對於相對較小的字符串來說不會有太大的區別,但是當你的正則表達式和字符串變大時,它可能會。

有關使用非捕獲組的更好示例,請參閱下面的Chris Lutz的評論。

+2

這不僅僅是爲了跑得更快。考慮這個:'/(\ w +)?\ s +(\ w +)/'可能有一組或兩組,我們不知道哪一個不檢查第二個是否存在。如果我們知道我們不需要第一組(基本上我們只是確定它存在),我們可以使用'/(?:\ w +)?\ s +(\ w +)/',然後我們知道數據we想要總是在組1中。(用\更復雜的正則表達式替換'\ w +'和'\ s +'以獲得一個合理的真實世界示例。) – 2009-10-16 09:28:57

+0

優秀的點Chris! – 2009-10-16 09:35:29

2

? =零或一個

使用(?:)對於分組的w/o保存組在臨時變量中,你會與()

1

?並不意味着「零個或多個」,就意味着「零或一個「。

4

?:< <我的書使用這個,它說它是一個「微妙」,但我不知道這些做什麼!

如果這確實是你的書所說的話,那麼我建議你找一本更好的書。

括號內(更確切地說:右括號後面),?有另一個含義。它啓動一組選項,其中只計算括號的範圍。 ?:是這些選項的特例。要理解這種特殊情況下,你必須先知道,括號創建捕捉組:

a(.)c 

這是一個正則表達式,任何三個字母組成的字符串開始ac結束匹配。中間的字符(或多或少)是多餘的。既然你把它放在括號中,你可以捕獲它:

m = re.search('a(.)c', 'abcdef') 
print m.group(1) 

這將打印b,因爲m.group(1)捕獲第一括號的內容(group(0)捕捉全命中,這裏abc)。

現在,考慮這個正則表達式:

a(?:.)c 

無捕獲這裏做 - 這是一個左括號意味着什麼之後?:。也就是說,下面的代碼將失敗:

print m.group(1) 

因爲沒有組1!