解析复杂的匹配分隔符

时间:2015-12-21 21:54:43

标签: python html pyparsing

像HTML-Tags这样的结构有一个开始和结束部分,共享一个相同的标签以使它们相互匹配。

<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", ...))。当匹配的标签集可能无限时,如何使标签匹配?

1 个答案:

答案 0 :(得分: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

希望它有所帮助。