使用正则表达式检测python函数?

时间:2015-10-10 20:48:13

标签: python regex

我想在python脚本中提取所有python函数。有没有我可以使用的单一正则表达式,例如:

import re
all_functions = re.findall(regex, python_script)

我已经实现了一个非常麻烦的方法,涉及许多if语句,但我觉得有一个更优雅的解决方案与正则表达式。

我认为正则表达式应该是这样的:

'def.*?\n\S'

,因为:

  1. 功能以def
  2. 开头
  3. 跟随任何事情(但我们想要非贪婪)
  4. 当换行符\n之后,下一行的起始字符不是空格\S
  5. 时,函数结束

    但是,我似乎无法通过多行工作。

    编辑:Python函数可能包含在没有.py扩展名的文件中;例如它们可以包含在.ipynb扩展名的IPython笔记本中,因此我不一定总是import代码并使用dir()

2 个答案:

答案 0 :(得分:8)

不要使用正则表达式。让Python为您解析代码,并使用ast module找到所有函数定义:

import ast

with open(python_sourcefile) as sourcefile:
    tree = ast.parse(sourcefile.read(), sourcefile.name)

for node in ast.walk(tree):
    if isinstance(node, ast.FunctionDef):
        print(node.name)

如果代码包含在.ipynb文件中,则解析文件并提取code单元格,然后通过相同的过程放置input源代码。

使用ast模块源本身进行演示:

>>> import ast
>>> with open(ast.__file__.rstrip('c')) as sourcefile:
...     tree = ast.parse(sourcefile.read(), sourcefile.name)
... 
>>> for node in ast.walk(tree):
...     if isinstance(node, ast.FunctionDef):
...         print(node.name)
... 
parse
literal_eval
dump
copy_location
fix_missing_locations
increment_lineno
iter_fields
iter_child_nodes
get_docstring
walk
_convert
_format
_fix
visit
generic_visit
generic_visit

答案 1 :(得分:1)

这个正则表达式可能适合你:

re.compile('def (?P<function>(?P<function_name>.*?)\((?P<function_args>.*)\)):')

我使用了群组,因此您可以使用匹配对象的groupdict()方法轻松获取信息,但如果您只想要声明行,则可以使用     re.compile('def .*?\(.*)\):')

这个正则表达式可能更紧凑(它接受def do something(1,2,3):即使它不是一个有效的函数),但是如果你的python文件在语法上是正确的并且你绝对想要使用正则表达式,这将为你完成这项工作。