如何使用regex查找函数调用self?

2024-09-28 22:02:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个code.py

def funA():
    print('A')
    funA()

def funB():
    print('B')

def funC():
    print('C')
    funB()
    funC()

我要找到所有函数都称为self:

^{pr2}$

如何编写regex?在

约束:

  • 所有函数调用正常:funname(arg1, arg2, ...)
  • 无模糊处理方式(如lambdaexec
  • 无间接递归

Tags: 函数pyselfdefcoderegexfuncprint
3条回答

这很难,因为函数可以以模糊的方式调用自己。E、 g,这算吗?在

def funA():
  print 'A'
  foo = funA
  foo()

funA()

这个怎么样?在

^{pr2}$

甚至这个?在

^{3}$

我觉得你用正则表达式做不到。在


即使考虑到你的新编辑,如果不是不可能的话,这仍然是非常困难的。以这个函数为例。在

def funA():
  if 1 + 1 == 2:
    return
  funA()

我建议你听从艾布拉姆斯的建议,看看ast。在

简单地说,使用regex是做不到这一点的。您至少需要解析函数定义,保持某种关于当前正在解析的函数的状态,并在当前函数的范围内搜索当前函数名的a调用。在

是的,我相信正则表达式不可能与wim指出的self-call混淆的情况相匹配。{1{self}在这里,self}是很直接的。此正则表达式正确匹配原始问题中列出的所有测试用例:

reobj = re.compile(r"""
    # Match (unreliably) Python function with self reference.
    ^                        # Anchor to start of line.
    ([ \t]*)                 # $1: Indentation of DEF statement.
    def[ \t]+                # Function definition.
    ([^\s(]+)                # $2: Name of function to find.
    .*\r?\n                  # Remainder of function def line.
    (?:                      # Zero or more lines w/o funcname.
      (?:                    # Function block lines alternatives.
        \1[ \t]+             # Func block lines have extra indentation.
        (?:(?!\b\2\s*\().)*  # Optional non-funcname stuff on line
      | [ \t]*\#.*           # Allow comment lines to defy indent rules.
      )?                     # Allow blank lines in function block.
      \r?\n                  # End of line not containing funcname.
    )*                       # Zero or more lines w/o funcname
    \1[ \t]+                 # Now match the line having funcname.
    (?:(?!\b\2\s*\().)*      # Optional non-funcname stuff on line
    \b\2\s*\(                # Match the function self reference.
    """, re.MULTILINE | re.VERBOSE)

它以函数定义行开始匹配,并捕获组$1'def'之前的空白缩进和组$2中的函数名。然后它匹配函数块中不包含函数名的行,这些行的前导空格多于函数定义。它跳过空行和只包含注释的行。它一旦在函数块中找到一行,该行的函数名后跟左括号,表示对自身的调用,就声明匹配。否则将继续查找下一个匹配项,否则将继续查找不匹配项。在

请注意,此解决方案是不可靠的,如果函数名出现在字符串中或某行中其他代码后面的注释中,则会导致误报。它也不处理包含多行原始字符串的函数。不过,它会正确捕捉到不少!在

相关问题 更多 >