python - 解析Python函数声明

标签 python regex

为了为我的Python代码编写一个自定义文档生成器,我想编写一个能够匹配以下内容的正则表达式:

def my_function(arg1,arg2,arg3):
"""
DOC
"""


我当前的问题是,使用以下正则表达式:

def (.+)\((?:(\w+),)*(\w+)\)


我只能匹配my_functionarg2arg3(根据Pythex.org)。

我不明白自己在做什么错,因为我的(?:(\w+),)*应该匹配尽可能多的参数,直到最后一个(这里是arg3)为止。谁能解释?

谢谢

最佳答案

从一般意义上讲这是不可能的,因为Python函数不是正则表达式-它们可以采用无法用正则表达式语法捕获的形式,尤其是在其他Python结构的上下文中。但是请振作起来,从您的问题中学到很多东西!

令人着迷的是,尽管您说过要尝试学习正则表达式,但是您还是偶然地偶然发现了计算机科学本身的核心,即编译器理论!

在这篇文章中,我将只介绍冰山一角,以帮助您起步,然后提供一些免费的有偿资源来帮助您继续。

python函数本身可以采取几种形式:

def foo(x):
    "docstring"
    <body>

def foo1(x):
    """doc
    string"""
    <body>

def foo2(x):
    <body>


此外,该功能前后的内容可能不是另一个功能!

这将使使用正则表达式本身无法自动生成文档(嗯,对我来说是不可能的。我不够聪明,无法编写单个正则表达式来解释整个Python语言!)。

您需要研究的是解析(顺便说一句,我使用的术语解析非常宽松,以覆盖parsing, tokenizing, and lexing只是为了使事情“简单”)。使用正则表达式通常是解析中非常重要的一部分。

一般的策略是将文件解析为语法构造。确定哪些构造是函数。隔离该函数的文本。然后,您可以使用正则表达式来解析该构造的文本。或者,您可以进一步解析一个级别,然后将函数分解为不同的语法结构-函数名称,参数声明,文档字符串,正文等...,此时将解决您的问题。

我试图为诸如foofoo1之类的标准函数定义(不进行解析)编写正则表达式,但是我一直在努力工作,即使编写了几种语言也是如此。

因此,为了清楚起见,我认为解析而不是简单的正则表达式的要点是,只要您的输入跨越多行。正则表达式在单行上最有效。

解析函数如下所示:

def parse_fn_definition(definition):

    def parse_name(lines):
       <code>

    def parse_args(lines):
       <code>

    def parse_doc(lines):
       <code>

    def parse_body(lines):
       <code>
    ...


现在这才是真正的把戏:这些parse函数每个都返回两件事:

0)解析的正则表达式块
1)线的REST

例如

def parse_name(lines):
    pattern = 'def\s*?([a-zA-Z_][a-zA-Z0-9_]*?)'
    for line in lines:
        m = re.match(pattern, line)
        if m:
            res, rest = m.groups()
            return res, [rest] + lines
        else:
            raise Exception("Line cannot be parsed by parse_name: {}".format(line))


因此,一旦您隔离了功能文本(这是另一套技巧,通常涉及创建称为“语法”的东西–不用担心,我在下面提供了一些资源),您可以使用以下技术解析函数文本:

def parse_fn(lines_of_text):
    name, rest = parse_name(lines_of_text)
    params, rest = parse_params(rest)
    doc_string, rest = parse_doc(rest)
    body, rest = parse_body(rest)
    function = [name, params, doc_string, body]
    res = function, rest
    return res


该函数将返回表示该函数的数据结构(我仅使用一个简单的list进行说明)和其余文本行。这将传递给可以适当地分类您的function数据,然后对文本的rest进行分类和处理的内容!

无论如何,如果这是您感兴趣的东西,请不要放弃!我会提出一些谦虚的建议:

1)从EASIER语言开始解析,例如Scheme / LISP。这些语言旨在易于解析和操作!然后逐步处理更多不规则的语言。

2a)彼得·诺维格(Peter Norvig)在此方面做了一些了不起的工作。签出Lispy

2b)彼得·诺维格(Peter Norvig)的班级CS212(特别是单元3 code)非常具有挑战性,但在介绍基本语言设计概念方面做得很好。我曾经获得的每一份工作,以及我对编程的热爱,就是因为那门课程。

3)如果您想进一步提高自己的能力,并且可以负担得起,我强烈建议您查看Dave Beazely在compilersinterpreters上的工作坊。我从戴夫(Dave)修了两门课程,虽然我不能为所有人保证,但是每门课程后我的薪水确实翻了一番,所以我认为这是值得的投资。

4)绝对签出计算机程序的结构和解释(向导书)和编译器(龙书)。他们会改变你的生活。

5)不要放弃!你有这个!祝你好运!

关于python - 解析Python函数声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49779932/

相关文章:

python - 使用 bash 脚本将文件中的各个行传递到 python 脚本中

python - PIL.ImageTk.PhotoImage 的更快替代方案是什么?

python - 如何在 python 3.4 中预处理 yaml 文件?

javascript - 如何使这个正则表达式与 JavaScript 兼容?

r - R中使用CamelCase分隔字符串中的标题和副标题

Python - Flask-SocketIO 从线程 : not always working 发送消息

python - 使用 pandas 数据框和组合条件会产生歧义错误

regex - 查找小写字母后跟大写字母的正则表达式

regex - 格式化 awk 输出

正则表达式:对文本文件中的所有实数进行四舍五入(保留 15 位小数)