2013-05-18 20 views
2

我試圖使用正則表達式來解析以(key###value)格式編寫的值。該值將始終是一個數字。無論如何,我想,這會,最簡單的用Python來做到這一點,所以這裏的一些代碼,我想:如何在同一行中分隔多個正則表達式匹配

import re 

line = "(text 1###123)(text 2###345)"; 

matchObj = re.match(r'\(.*###[0-9]+\)', line) 

if matchObj: 
    print matchObj.group(0) # produces (text 1###123)(text 2###345) 
    # print matchObj.group(1) # gives an error 
else: 
    print "No match!!" 

即使有匹配的,我寫的正則表達式兩個不同的對象,蟒蛇回到他們以我爲一個字符串 - 不是我想要的。我怎樣才能解決這個問題?

實際上,我真正想要的是將字符串分隔成類似["text 1", "123", "text 2", "345]的東西。所以如果有人有一個簡單的方法來實現這一點,我也非常感謝。

回答

4

你沒有這個正確的正則表達式,你需要有捕獲組。你的例子有parens逃脫。這是您實際需要的正則表達式。 *之後的?使其非貪婪(以便它儘可能少的字符而仍然匹配)。

\((.*?)###([0-9]+)\) 

你目前的正則表達式只有逃脫的parens,所以你實際上沒有任何捕獲組。要獲得所有比賽,您需要使用re.findall。但是,如果你需要使用兩個捕獲組,這將產生這樣的事情:

regex = r'\((.*?)###([0-9]+)\)' 
re.findall(regex, "(text 1###123)(text 2###345)") # [("text 1", "123"), ("text 2", "345")] 

如果你想變平,這是相當簡單的事情爲好。

+0

非貪婪'(。*?)'是必要的在這裏,否則'findall'返回'[('text 1 ### 123)(text 2','345')]' –

+0

@JanneKarila好點。我想我最初是以'[^#] *'的形式出現的,然後決定這會做出太多的假設,所以不用考慮它就回到'。*'。 –

1

在這個問題上有幾點發揮作用。

  1. 首先是什麼re.match()確實。這個函數實際上希望能夠在字符串的開頭處開始匹配,在這種情況下,它不能像在那裏有一個左括號。所以你會想看看re.search(),更可能的是re.findall()函數。
  2. 此外,您不需要像在其他語言中那樣在Python中轉義組。
  3. 您可能不想使用.*,因爲這往往是貪婪的。雖然你可以通過.*?逃脫,但花時間爲正則表達式提供更具體的搜索通常會更好。

綜上所述,筆者提出以下建議:

matchObj = re.findall(r'(([\w\d ]+)###(\d+))', line) 

這將導致一個易於陣列通過排序:

>>> matchObj 
[('text 1###123', 'text 1', '123'), ('text 2###345', 'text 2', '345')] 
>>> matchObj[0] 
('text 1###123', 'text 1', '123') 
+0

小錯誤:'\('是匹配開始paren,所以're.match()'應該處理它只返回一個結果的異常。如果你添加了escape到我的第一個和最後一個parens,那麼你的結果可能會更好:'('text 1','123'),('text 2','345')]' – Mike

相關問題