2013-01-09 75 views
1

我今天早些時候提出了一個關於同樣問題的問題,但是因爲解決方案是切換庫,我現在有一個與其他庫的問題,我想打開另一個問題...希望沒關係。PyParsing - nestedExpr和匹配標記

所以我wan't以匹配下面的標記:

<text link="no"> 
    ... 
</text> 

我不關心裏面有什麼文字是什麼matherrs是文本具有鏈接屬性。

現在,我使用pyparsing如下:

def content_must_not_be_empty_string(tokens): 
    if tokens[0]=="": 
     raise ParseException("content cannot be empty") 

text_start = Regex('<text[^<]*>') 
text_no_start = Regex('<text[^<]*link="no"[^<]*>') 
text_no_end = Regex('</text>[ \t\n\r\xa0]*') 
text_no_content = SkipTo(text_no_start | text_no_end | text_start) 
text_no_content.setParseAction(content_must_not_be_empty_string) 
text_no = nestedExpr(text_no_start,text_no_end,text_no_content) 
text_no.setParseAction(somemethod) 

起初,整個事情循環,因爲空標記的,這就是爲什麼我添加content_must_not_be_empty。

現在它不再循環,但是somemethod也不會執行。

幫助將不勝感激。

+0

您的樣品不顯示任何嵌套,是標籤真的嵌套,或者你只是使用nestedExpr實施的標籤打開/關閉? – PaulMcG

+0

在文本中有一個嵌套,很難說這是多少,這就是爲什麼我儘量保持一般 – pypat

回答

2

嚴格地說,pyparsing不是一個XML解析庫,但它確實包含了一些內置支持,用於從XML和HTML中提取數據,而不需要解析整個文檔。我並不是說你可以在正則表達式裏嵌入正則表達式。相反,看看使用makeXMLTags或makeHTMLTags:

>>> sample = """<text link="no"> lskdjflskdjf </text>""" 
>>> text_start,text_end = makeXMLTags("text") 
>>> text_start_no = text_start.copy().setParseAction(withAttribute(link="no")) 
>>> expr1 = text_start_no + SkipTo(text_end)('body') + text_end 
>>> print expr1.parseString(sample) 
['text', ['link', 'no'], False, 'lskdjflskdjf ', '</text>'] 
>>> print expr1.parseString(sample).dump() 
['text', ['link', 'no'], False, 'lskdjflskdjf ', '</text>'] 
- body: lskdjflskdjf 
- empty: False 
- endText: </text> 
- link: no 
- startText: ['text', ['link', 'no'], False] 
    - empty: False 
    - link: no 

提取XML或HTML數據時,這將讓你周圍的各種意外的。

現在,如果您實際上有嵌套標記,那麼您將需要開始鑽研nestedExpr區域。

>>> sample2 = """<text link="no"> lskdjflskdjf<text>more</text> </text>""" 

但我仍鼓勵您使用makeXMLTags或makeHTMLTags來構建標記構造,而不是用正則表達式來僞造它。

0

這是我現在的工作的一段代碼:

def content_must_not_be_empty_string(tokens): 
    if tokens[0]=="": 
     raise ParseException("content cannot be empty") 

text_no_start = Regex('<text[^<]*link="no"[^<]*>') 
text_no_end = Regex('</text>[ \t\n\r\xa0]*') 
text_no_content = SkipTo(text_no_start | text_no_end) 
text_no_content.setParseAction(content_must_not_be_empty_string) 
text_no = originalTextFor(nestedExpr(text_no_start,text_no_end,text_no_content), asString="False") 
text_no.setParseAction(somemethod) 
+0

請考慮您的標記表達式的非正則表達式形式發佈在我的其他答案。這個代碼是非常脆弱的,受到意想不到的空白位置,屬性等的影響。 – PaulMcG

+0

會做,thx提醒我:) – pypat