解析Python函数的类名

时间:2015-06-26 15:12:17

标签: python regex abstract-syntax-tree

我正在尝试查找调用函数名的类名。

E.g。假设我有:

class foo1(object):
    bar1()

class foo2(object):
    bar2()

class foo3(object):
    bar3()

如果我正在搜索bar2(),我想收到:

class foo2(object):
    bar2()

我试过正则表达式class[\s\S]*bar2\(\)(?!class)的想法是我会对另一个类的外观负面预测。不幸的是,[\ s \ S]似乎已经匹配了所有内容:https://regex101.com/r/kZ7eE5/1

有没有办法匹配if" class"在匹配所有其他字符(包括新行和制表符)时只出现一次?

也可以接受不需要正则表达式的替代方案。

3 个答案:

答案 0 :(得分:5)

RE方法可能容易出错(Python语言的表达能力比RE识别的常用语言更强)。

使用Python的ast模块解析Python代码:

code = '''
class foo1(object):
    bar1()

class foo2(object):
    bar2()

class foo3(object):
    bar3()
'''

>>> import ast
>>> tree = ast.parse(code)
>>> for i in tree.body:
...     if isinstance(i, ast.ClassDef):
...         print('class: %s' % i.name)
...
class: foo1
class: foo2
class: foo3
>>>

您可以执行许多其他操作,请查看https://greentreesnakes.readthedocs.org/en/latest/

上的文档

编辑:一个更完整的例子:

>>> for i in tree.body:
...     if isinstance(i, ast.ClassDef):
...         for j in i.body:
...             if isinstance(j, ast.Expr):
...                 print('found a call to function %s in class %s' % (j.value.func.id, i.name))
...
found a call to function bar1 in class foo1
found a call to function bar2 in class foo2
found a call to function bar3 in class foo3

答案 1 :(得分:1)

以下代码打印包含存储在function变量中的方法调用的类。这是您需要执行的操作:

import re

data = """
class foo1(object):
    bar1()

class foo2(object):
    bar2()

class foo3(object):
    bar3()
"""

classes = re.findall('(class[\s\S]*?)(?=class|$)',data)
function = "bar2()"
for x in classes:
    if function in x:
        matched_class = x
        break
print(matched_class)

输出:

class foo2(object):
    bar2()

答案 2 :(得分:0)

[\s\S]*匹配所有内容的原因是因为您所说的是要匹配任何空格字符(\s)或任何非空格字符(\S)任意次。您可以在正则表达式中将空间与空间匹配。通常。有例外,但python要求这种形式,所以应该没问题。

您可以使用

^class ([\w]+)\([^)]+\):

演示: https://regex101.com/r/aB9pX4/2