为了为我的Python代码编写一个自定义文档生成器,我想编写一个能够匹配以下内容的正则表达式:
def my_function(arg1,arg2,arg3):
"""
DOC
"""
我当前的问题是,使用以下正则表达式:
def (.+)\((?:(\w+),)*(\w+)\)
我只能匹配
my_function
,arg2
和arg3
(根据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只是为了使事情“简单”)。使用正则表达式通常是解析中非常重要的一部分。
一般的策略是将文件解析为语法构造。确定哪些构造是函数。隔离该函数的文本。然后,您可以使用正则表达式来解析该构造的文本。或者,您可以进一步解析一个级别,然后将函数分解为不同的语法结构-函数名称,参数声明,文档字符串,正文等...,此时将解决您的问题。
我试图为诸如
foo
或foo1
之类的标准函数定义(不进行解析)编写正则表达式,但是我一直在努力工作,即使编写了几种语言也是如此。因此,为了清楚起见,我认为解析而不是简单的正则表达式的要点是,只要您的输入跨越多行。正则表达式在单行上最有效。
解析函数如下所示:
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在compilers或interpreters上的工作坊。我从戴夫(Dave)修了两门课程,虽然我不能为所有人保证,但是每门课程后我的薪水确实翻了一番,所以我认为这是值得的投资。
4)绝对签出计算机程序的结构和解释(向导书)和编译器(龙书)。他们会改变你的生活。
5)不要放弃!你有这个!祝你好运!
关于python - 解析Python函数声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49779932/