如何在Python中解析重构文本?

28

有没有可以将重构文本解析为树形模型的模块?

docutils或sphinx能否完成此任务?


重构文本是什么意思? - Ionut Hulub
2
@IonutHulub http://docutils.sourceforge.net/rst.html - Gareth Latty
4个回答

42

我想在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

然后可以使用以下方式处理生成的文档,例如下面的方法,它将打印文档中的所有参考文献:

And the resulting document can be processed using, for example, below, which will print all references in the 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)

我该如何取消解析它?也就是说,在对节点进行一些修改后,如何从一系列节点返回到.rst文件? - user3064538
4
谢谢你提供的代码样例!有趣的是,docutils 是我尝试使用过的任何库中文档最差的一个(但至少它文档)。 - user3064538
Unparsing - 这是完全不同的问题,我鼓励您单独提问,除非当然已经有人问过了!目前我不知道任何具体的解决方案。 - mbdevpl
如何将重构文本重新转换为rst文件? - user3064538
推荐的方法是使用docutils.core提供的“发布者便利函数”(https://docutils.sourceforge.io/docs/api/publisher.html#publisher-convenience-functions)。 - undefined

18

Docutils确实包含了完成此操作所需的工具。

您可能需要的是docutils.parsers.rst中的解析器。

有关涉及内容的详细信息,请参见此页面。还有一些示例在docutils/examples.py中,尤其是要查看internals()函数,这可能会引起您的兴趣。


4
补充一下,Docutils是reStructuredText的参考实现,而Sphinx则是在Docutils的基础上构建的。因此,是的,Docutils绝对是这个任务的正确工具。 - Chris

0

基于 Gareth Latty 和 mbdevpl 在此的答案,这是 docutils 新版本的更新。

从 docutils 0.18(2021-10-26)开始,docutils.frontend.OptionParser已被弃用(git镜像提交} },{{link2:上游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的答案中找到。


0

docutils.core 模块中有一个更高级别的 Docutils 接口。要将一串 reStructuredText 解析成文档树,请执行以下操作:

from docutils.core import publish_doctree
source = 'Hello *world*'
tree = publish_doctree(source)

详情请参见https://docutils.sourceforge.io/docs/api/publisher.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接