2011-06-06 76 views
1

在下面的例子中,我想製作一個正則表達式來查找一行中最後一組連續1位數字。python正則表達式問題,? op

據我所知,在python3中,re.search()遍歷搜索字符串,試圖從左到右進行匹配。

是否解釋了以下示例中的行爲?具體而言,這就是爲什麼'。*?'需要在捕獲塊之前(當錨定在前面時,如前兩個例子),以便捕獲塊捕獲兩個數字,而'?'是可選的,當正則表達式被錨定到該行的末尾

Python 3.1.2 (release31-maint, Sep 17 2010, 20:27:33) 
>>> import re 
>>> a = "hi there in the morning {23)" 
>>> R = re.compile('^.*(\d+)', re.IGNORECASE); print(R.search(a).group(1)) 
3 
>>> R = re.compile('^.*?(\d+)', re.IGNORECASE); print(R.search(a).group(1)) 
23 
>>> R = re.compile('(\d+).*$', re.IGNORECASE); print(R.search(a).group(1)) 
23 
>>> R = re.compile('(\d+).*?$', re.IGNORECASE); print(R.search(a).group(1)) 
23 

回答

4
  • ^.*(\d+) - 從頭開始​​匹配。 .*將一路匹配到行的末尾,然後\d+將使.*原路返回(取消以前的比賽),只需根據需要,所以\d+只會匹配最後一位
  • ^.*?(\d+) - 從頭開始​​匹配。起初,.*?什麼都不匹配。 \d+將在稍後失敗(如果第一個字符不是數字),使.*?回溯,並匹配額外字符,直到找到第一個數字,然後+將匹配後面的所有數字。對於abc123edf567,模式將匹配123,第一組數字
  • (\d+).*$ - \d+將匹配第一組數字.*$將始終成功並一直匹配到最後。
  • (\d+).*?$ - 這個實際上是一樣的(儘管可以說是稍微慢一些)。 \d+將匹配第一組數字.*?$最初不會匹配,但隨後會匹配越來越多的字符,直到達到$。請記住*?是左邊懶,但它並不意味着引擎將從右邊需要少量字符。

您可能要查找的是(\d+)\D*$ - 匹配一組字符,後面緊跟着非字符和行尾。這將返回最後一組數字

參見:regular-expressions.info - Laziness Instead of Greediness

+0

哇,這是一個很棒的答案。我想我的測試字符串有點天真。我想我需要更小心一點,「用正則表達式思考」。另外,我並沒有考慮回溯。謝謝。 – 2011-06-06 17:44:52

+0

@Ryan - 謝謝!沒問題。 – Kobi 2011-06-06 17:51:08

3

其本身而言,*是貪婪(如最後兩個例子);它會盡可能地匹配,同時允許整個正則表達式匹配,因此.*會吞噬除了匹配\d+所需的單個數字之外的所有內容。

*?使用非貪婪匹配,所以只有非數字匹配。

0

正如Wooble說,*是貪婪的,所以在你的字符串的第一個例子,對於貪婪的比賽。 *?將是hi there in the morning {2,因爲\d+將是正確的,只有一個值,3