如何在 python 中解析重组文本?

问题描述 投票:0回答:3

有没有模块可以将restructuredtext解析成树模型?

docutils 或 sphinx 可以这样做吗?

python parsing dom restructuredtext
3个回答
41
投票

我想扩展 Gareth Latty 的回答。 “您可能想要的是

docutils.parsers.rst
处的解析器”是一个很好的答案起点,但下一步是什么?即:

如何在 python 中解析重组文本?

以下是 Python 3.6 和 docutils 0.14 的确切答案:

import docutils.nodes
import docutils.parsers.rst
import docutils.utils
import docutils.frontend

def parse_rst(text: str) -> docutils.nodes.document:
    parser = docutils.parsers.rst.Parser()
    components = (docutils.parsers.rst.Parser,)
    settings = docutils.frontend.OptionParser(components=components).get_default_values()
    document = docutils.utils.new_document('<rst-doc>', settings=settings)
    parser.parse(text, document)
    return document

并且可以使用例如下面的方法处理生成的文档,它将打印文档中的所有引用:

class MyVisitor(docutils.nodes.NodeVisitor):

    def visit_reference(self, node: docutils.nodes.reference) -> None:
        """Called for "reference" nodes."""
        print(node)

    def unknown_visit(self, node: docutils.nodes.Node) -> None:
        """Called for all other node types."""
        pass

运行方法如下:

doc = parse_rst('spam spam lovely spam')
visitor = MyVisitor(doc)
doc.walk(visitor)

18
投票

Docutils 确实包含执行此操作的工具。

您可能想要的是

docutils.parsers.rst

处的解析器

有关所涉及内容的详细信息,请参阅本页

docutils/examples.py
也有一些示例 - 特别是查看
internals()
函数,这可能很有趣。


0
投票

根据 Gareth Latty 和 mbdevpl 的回答,此处更新了较新版本的 docutils。

从docutils 0.18(2021-10-26)开始,

docutils.frontend.OptionParser
已经被弃用(git mirror commitupstream SVN HISTORY.txt),会打印如下警告(source):

DeprecationWarning: The frontend.OptionParser class will be replaced by a subclass of argparse.ArgumentParser in Docutils 0.21 or later.

可以使用

docutils.frontend.get_default_settings()
函数代替,但它只在docutils 0.18中添加,所以要兼容所有版本而不会收到警告,您可以使用:

import docutils.parsers.rst
import docutils.utils
import docutils.frontend

def parse_rst(text: str) -> docutils.nodes.document:                                                                                                     
    parser = docutils.parsers.rst.Parser()                                                                               
    if hasattr(docutils.frontend, 'get_default_settings'):
        # docutils >= 0.18
        settings = docutils.frontend.get_default_settings(docutils.parsers.rst.Parser)                                                       
    else:
        # docutils < 0.18
        settings = docutils.frontend.OptionParser(components=(docutils.parsers.rst.Parser,)).get_default_values()
    document = docutils.utils.new_document('<rst-doc>', settings=settings)                                               
    parser.parse(text, document)                                                                                         
    return document                                                                                                      

其余代码保持不变,可以在 mbdevpl 的答案中找到。

© www.soinside.com 2019 - 2024. All rights reserved.