2012-09-20 16 views
0

可能重複:
Matching Nested Structures With Regular Expressions in Python正則表達式 - 如何與子組工作

我試圖從一個wiki頁面匹配數據的一個組。下面列出了我使用的python代碼。問題在於,它返回到自己組的最後一個頁面中的最後一個}}

def findPersonInfo(self): 
    if (self.isPerson == True): 
     regex = re.compile(r"{{persondata(.*)}}",re.IGNORECASE|re.UNICODE|re.DOTALL) 
     result = regex.search(self._rawPage) 
     if result: 
      print 'Match found: ', result.group() 

wiki頁面內容的示例:

*[http://www.jsc.nasa.gov/Bios/htmlbios/acaba-jm.html NASA biography] 

{{NASA Astronaut Group 19}} 

{{Persondata 
|NAME= Acaba, Joseph Michael "Joe" 
|ALTERNATIVE NAMES= 
|SHORT DESCRIPTION=[[Hydrogeologist]] 
|DATE OF BIRTH={{Birth date and age|1967|5|17}} 
|PLACE OF BIRTH=[[Inglewood, California]] 
|DATE OF DEATH= 
|PLACE OF DEATH= 
}} 
{{DEFAULTSORT:Acaba, Joseph M.}} 
[[Category:1967 births]] 

我現在的正則表達式將返回以下字符串:

{{Persondata 
|NAME= Acaba, Joseph Michael "Joe" 
|ALTERNATIVE NAMES= 
|SHORT DESCRIPTION=[[Hydrogeologist]] 
|DATE OF BIRTH={{Birth date and age|1967|5|17}} 
|PLACE OF BIRTH=[[Inglewood, California]] 
|DATE OF DEATH= 
|PLACE OF DEATH= 
}} 
{{DEFAULTSORT:Acaba, Joseph M.}} 

我想它返回:

{{Persondata 
|NAME= Acaba, Joseph Michael "Joe" 
|ALTERNATIVE NAMES= 
|SHORT DESCRIPTION=[[Hydrogeologist]] 
|DATE OF BIRTH={{Birth date and age|1967|5|17}} 
|PLACE OF BIRTH=[[Inglewood, California]] 
|DATE OF DEATH= 
|PLACE OF DEATH= 
}} 

棘手的是它需要計數其他r {{打開並}}關閉以知道我想要停止的組,但我不知道如何讓正則表達式來做到這一點。

+0

你應該使用一個合適的[Wiki解析器](http://www.mediawiki.org/wiki/Alternative_parsers)...這不是一個普通的語言BTW – JBernardo

+0

@JBernardo - 我不需要一個完整的解析器,我只是需要完整頁面中的一個部分,我可以將其分成鍵/值對。 – Justin808

+2

@ Justin808這就是爲什麼你需要一個解析器。正則表達式不適用於任意深度的語言。您*可以*使其適用於某些特定情況,但不應該 – JBernardo

回答

2

{{persondata(.*)}}會貪婪地匹配。即它會嘗試返回儘可能長的比賽。如果你想獲得最短的匹配,你應該使用{{persondata(.*?)}}。 (是不是有這個名字,也許節儉匹配?)

但是,在這種情況下,你的字符串中有另一個}}。你可以像{{persondata((?:.*)}}(?:.*))}}那樣聰明,但一般來說,只要你到達遞歸結構(嵌套自己的結構),你應該放棄正則表達式並轉向正確的解析解決方案。您可能想要查看pyparsing

+0

或'r「{{persondata([^}] *)}}」'假設沒有嵌套花括號... –

+2

但是這會給出一個同樣錯誤的結果, |出生日期= {{出生日期和年齡| 1967 | 5 | 17}}''。 – ruakh

+0

所以在標準python中這樣做的唯一方法是不使用正則表達式並編寫我的一個函數來處理遞歸大括號?似乎很奇怪,我用過的其他語言似乎都支持沒有外部庫的遞歸。 – Justin808

相關問題