2015-12-21 59 views
1

結構如HTML的標籤具有開口和封閉部,共享相同的標籤,以匹配他們彼此。解析複雜匹配的分隔符

<tag> ... </tag> 

我想使用pyparsing庫來捕獲這些對和它們的內容。我知道如何指定一個標籤。

from pyparsing import SkipTo, makeHTMLTags 
open, close = makeHTMLTags("tag") 
(open + SkipTo(close) + close).parseString("<tag> Tag content </tag>") 
# yields ['tag', False, 'Tag content ', '</tag>'] 

我也知道,指定多個不同的標籤時,他們每個人都需要一個專門的規則,以避免一個標籤關閉另一個。因此,當一組標籤是Or(("tag", "other"))只是延長了前者的例子

from pyparsing import SkipTo, makeHTMLTags, Or 
open, close = makeHTMLTags(Or(("tag", "other"))) 
(open + SkipTo(close) + close).parseString("<other><tag> Tag content </tag></other>") 
# yields ['other', False, '<tag> Tag content ', '</tag>'] 

產生了不匹配的標籤。解析器關閉開口<other></tag>。這可以通過爲每個標籤指定專用規則來修改。

from pyparsing import SkipTo, makeHTMLTags, Or 
Or((
    open + SkipTo(close) + close 
    for open, close in 
    map(makeHTMLTags, ("tag", "other")) 
)).parseString("<other><tag> Tag content </tag></other>") 
# yields ['other', False, '<tag> Tag content </tag>', '</other>'] 

現在我可以,例如,想找到的所有標籤開始t,從而尋找Word('t', alphas),而不是Or(("tag", "other", ...))。如果要匹配的標記集合可能無限,我如何才能使標記匹配?

回答

0

我不熟悉pyparsing模塊,但你的問題似乎可以通過lxml(Library for processing XML and HTML in Python)解決。以下是使用lxml的我的示例代碼:

# -*- coding: utf-8 -*- 
from lxml import etree 


def pprint(l): 
    for i, tag in enumerate(l): 
     print 'Matched #%s: tag name=%s, content=%s' % (i + 1, tag.tag, tag.text) 


def main(): 
    # Finding all <tag> tags 
    pprint(etree.HTML('<tag>Tag content</tag>').xpath("//tag")) 

    # Finding all stags starts with "t" 
    pprint(etree.HTML('<tag>tag1 content</tag><tag2>tag2 conent</tag2><other>other</other>').xpath(
     "//*[starts-with(local-name(), 't')]")) 


if __name__ == '__main__': 
    main() 

這將輸出:

Matched #1: tag name=tag, content=Tag content 
Matched #1: tag name=tag, content=tag1 content 
Matched #2: tag name=tag2, content=tag2 conent 

希望它能幫助。