2011-10-19 160 views
4

我需要解析包含xml註釋的文件。具體來說,它是一個使用MS ///慣例的c#文件。pyparsing - 解析xml註釋

從這我需要拉出foobar,或/// foobar也是可以接受的。 (注 - 這仍然如果讓XML都在同一行不行?)

testStr = """ 
    ///<summary> 
    /// foobar 
    ///</summary> 
    """ 

以下是我有:

import pyparsing as pp 

_eol = pp.Literal("\n").suppress() 
_cPoundOpenXmlComment = Suppress('///<summary>') + pp.SkipTo(_eol) 
_cPoundCloseXmlComment = Suppress('///</summary>') + pp.SkipTo(_eol) 
_xmlCommentTxt = ~_cPoundCloseXmlComment + pp.SkipTo(_eol) 
xmlComment = _cPoundOpenXmlComment + pp.OneOrMore(_xmlCommentTxt) + _cPoundCloseXmlComment 

match = xmlComment.scanString(testStr) 

和輸出:

for item,start,stop in match: 
    for entry in item: 
     print(entry) 

但是我並沒有在跨多線工作的語法方面取得太大的成功。

(注意 - 我在Python 3.2測試上面的示例,它的工作原理,但(按我的問題)不打印任何值)

謝謝!

回答

2

如何使用nestedExpr

​​
+0

@ PaulMcGuire的解決方案也可以工作,但這正是我應該使用的(這是最簡單的......)Thansk! – mike

2

我認爲Literal('\n')是你的問題。你不想用空白字符構建Literal(因爲在嘗試匹配之前,Literals默認跳過空白)。改爲使用LineEnd()

編輯1: 僅僅因爲你得到LineEnd無限循環並不意味着文字(「\ n」)是更好。嘗試在_eol定義的末尾添加.setDebug(),並且您會看到它從不匹配任何內容。

,而不是試圖定義您的評論的身體「是不是收線的一行或多行,但得到的一切到最後的行」,如果你只是做:

xmlComment = _cPoundOpenXmlComment + pp.SkipTo(_cPoundCloseXmlComment) + _cPoundCloseXmlComment 

(您使用LineEnd()獲得無限循環的原因是您基本上在做OneOrMore(SkipTo(LineEnd())),但從不使用LineEnd(),因此OneOrMore只是保持匹配和匹配以及匹配,解析並返回一個空字符串,因爲解析位置是行末。)

+0

感謝您的建議;然而改變爲'_eol = pp.LineEnd()。suppress()'會導致hang/inf循環。你可能是更具體的litte(注意 - 將3個部分粘貼在一個.py文件中,代碼按原樣運行)。謝謝,邁克 – mike

+0

投票瞭解釋什麼是錯的。咄!我應該看到,我從來沒有消耗過行:) – mike

1

您可以使用xml解析器來解析xml。應該很容易提取相關注釋行:

import re 
from xml.etree import cElementTree as etree 

# extract all /// lines 
lines = re.findall(r'^\s*///(.*)', text, re.MULTILINE) 

# parse xml 
root = etree.fromstring('<root>%s</root>' % ''.join(lines)) 
print root.findtext('summary') 
# -> foobar 
+0

我以爲你在Blade Runner中很棒。 – PaulMcG

+0

@JFSebastian不幸的是,這在我遇到這個問題的大圖中是行不通的。是的,我可以按照你的建議提取所有的xml片段,但是我還需要在評論之後解析源代碼,並且需要一個語法分析器;逐行執行正則表達式搜索會在文件中添加一個額外的循環。 – mike

+1

@mike:正則表達式只是一個如何提取註釋行的例子。在更大的圖片中,您使用解析器來提取相關注釋(比解析xml更簡單的任務),並且不會妨礙您在發現必要時使用xml解析器來解析xml。 – jfs