Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用正则表达式检测python函数?_Python_Regex - Fatal编程技术网

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

使用正则表达式检测python函数?,python,regex,Python,Regex,我想取出python脚本中的所有python函数。我是否可以使用任何一个正则表达式来执行此操作,例如: import re all_functions = re.findall(regex, python_script) 我已经实现了一种非常麻烦的方法来实现这一点,它涉及许多if语句,但我觉得有一种更优雅的解决方案使用正则表达式 我认为正则表达式应该是这样的: 'def.*?\n\S' 因为: 函数以def开头 后面跟着任何东西(但我们不想贪婪) 当换行符\n之后的下一行的起始字符不是空格\

我想取出python脚本中的所有python函数。我是否可以使用任何一个正则表达式来执行此操作,例如:

import re
all_functions = re.findall(regex, python_script)
我已经实现了一种非常麻烦的方法来实现这一点,它涉及许多if语句,但我觉得有一种更优雅的解决方案使用正则表达式

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

'def.*?\n\S'
因为:

  • 函数以def开头
  • 后面跟着任何东西(但我们不想贪婪)
  • 当换行符
    \n
    之后的下一行的起始字符不是空格
    \S
  • 然而,我似乎无法在多行上实现这一点


    编辑:Python函数可能包含在没有扩展名
    .py
    的文件中;e、 g.它们可以包含在扩展名为
    .ipynb
    的IPython笔记本中,因此我不必总是
    导入
    代码并使用
    dir()
    不要使用正则表达式。让Python为您分析代码,并使用以下命令查找所有函数定义:

    如果代码包含在
    .ipynb
    文件中,则解析该文件并提取
    code
    单元格,然后通过相同的过程从这些单元格中输入
    源代码

    使用
    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
    

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

    re.compile('def(?p(?p.*)\(?p.*):')

    我使用了组,因此您可以使用match对象的groupdict()方法轻松地获取信息,但是如果您只需要声明行,那么可以使用
    re.compile('def.*?\(.*):')


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

    为什么不将它作为模块导入,通过
    dir
    查看其内容并检查其类型?如果代码是可信的,当然要感谢您的建议,但我一直在寻找一种适用于所有文件类型的解决方案,例如,有时IPython笔记本中的python函数具有.ipynb扩展名,因此,正则表达式可以让我从这些文件类型中提取函数
    def
    后面不能跟“任何东西”,这里有一个标识符的定义。也许你应该研究一下Python的语法?另外,如果您希望
    包含所需的换行符
    re.DOTALL
    .jornsharpe,您是对的,正则表达式应该更具体,可能类似于
    'def[A-Za-z_][A-Za-z_0-9]*?\(.?\)'
    ,假设文件中只包含编写良好的python函数,我认为应该检测函数的开头。“1.函数以def开头”。这几乎是完全错误的。它们可以分配给变量,从代码对象合成,用
    lambda
    语句匿名构建,分配给
    globals()
    字典中的键,或者在
    eval
    抬起丑陋的头的任何地方都像魔术一样出现。。。我肯定我错过了一些。一般来说,您不能使用正则表达式来解析像Python这样的非正则语言。这是不可能的,除非是在非常有限的情况下。。。即使这样,也只有在您已经确切知道要查找什么的情况下。谢谢,ast库看起来很酷,我会尝试使用它。谢谢Akshay,但我正在尝试获取整个函数,而不仅仅是函数名,因此正则表达式需要以类似“\n\S”的形式终止,并且还需要匹配多行。
    >>> 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