为了为我的 Python 代码编写自定义文档生成器,我想编写一个能够匹配以下内容的正则表达式:
def my_function(arg1,arg2,arg3):
"""
DOC
"""
Run Code Online (Sandbox Code Playgroud)
我当前的问题是,使用以下正则表达式:
def (.+)\((?:(\w+),)*(\w+)\)
Run Code Online (Sandbox Code Playgroud)
我只能匹配my_function, arg2and arg3(根据 Pythex.org)。
我不明白我做错了什么,因为我(?:(\w+),)*应该匹配尽可能多的参数,直到最后一个(此处arg3)。有人能解释一下吗?
谢谢
这在一般意义上是不可能的,因为 Python 函数不是正则表达式——它们可以采用正则表达式语法无法捕获的形式,特别是在其他 Python 结构的上下文中。但请放心,从你的问题中可以学到很多东西!
令人着迷的是,尽管您说您正在尝试学习正则表达式,但您却意外地陷入了计算机科学本身的核心,即编译器理论!
我将在这篇文章中介绍不到冰山一角的一小部分,以帮助您入门,然后建议一些免费和付费资源来帮助您继续。
python 函数本身可以采用多种形式:
def foo(x):
"docstring"
<body>
def foo1(x):
"""doc
string"""
<body>
def foo2(x):
<body>
Run Code Online (Sandbox Code Playgroud)
另外,之前和之后发生的事情内容可能不是另一个函数!
这就是使用正则表达式本身不可能自动生成文档的原因(好吧,对我来说不可能。我不够聪明,无法编写一个可以解释整个 Python 语言的正则表达式!)。
您需要研究的是解析(顺便说一句,我非常宽松地使用术语解析 来涵盖解析、标记化和词法分析,只是为了让事情保持“简单”)使用正则表达式通常是解析的一个非常重要的部分。
一般策略是将文件解析为语法结构。确定哪些构造是函数。隔离该函数的文本。然后您可以使用正则表达式来解析该构造的文本。或者,您可以进一步解析一个级别,并将函数分解为不同的语法结构——函数名称、参数声明、文档字符串、正文等……此时您的问题将得到解决。
我试图为标准函数定义(不解析)编写正则表达式,例如fooor 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>
...
Run Code Online (Sandbox Code Playgroud)
现在真正的技巧是:每个parse函数都返回两个内容:
0) 解析的正则表达式块 1) 行的其余部分
例如,
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))
Run Code Online (Sandbox Code Playgroud)
因此,一旦你隔离了函数文本(这是一套完整的其他技巧,通常涉及创建称为“语法”的东西 - 别担心,我在下面为你设置了一些资源),你可以使用以下技术解析函数文本:
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
Run Code Online (Sandbox Code Playgroud)
该函数将返回一些表示该函数的数据结构(我只是使用了一个简单的list示例)和其余文本行。这将被传递到适当地对您的function数据进行分类,然后对rest文本进行分类和处理的东西!
无论如何,如果这是您感兴趣的事情,请不要放弃!我想提供一些粗浅的建议:
1)从更容易解析的语言开始,例如Scheme/LISP。这些语言被设计为易于解析和操作!然后逐步学习更不规则的语言。
2a) Peter Norvig 在这方面做了一些令人惊奇且非常容易理解的工作。看看Lispy!
2b) Peter Norvig 的CS212类(具体为第 3 单元代码)非常具有挑战性,但在介绍基本语言设计概念方面做得非常出色。我得到的每一份工作以及我对编程的热爱都是因为那门课程。
3) 如果您想进一步提升自己并且负担得起,我强烈建议您查看 Dave Beazely 的编译器或解释器研讨会。我已经从戴夫那里学习了两门课程,虽然我不能向每个人保证这一点,但每门课程后我的工资实际上翻了一番,所以我认为这是一项值得的投资。
4)一定要看看《计算机程序的结构和解释》(向导书)和《编译器》(龙书)。他们会改变你的生活。
5)不要放弃!你得到了这个!祝你好运!
| 归档时间: |
|
| 查看次数: |
1418 次 |
| 最近记录: |