用于Python函数签名的Python正则表达式

时间:2012-04-14 23:59:28

标签: python regex

我尝试编写一个python正则表达式,它匹配简单python函数的签名。 像:

def _func1_(arg1, arg2):

我创建了这个正则表达式:

"def ([^\W\d]+\w*)(\(( *[^\W\d]+\w* *,? *)*\)):"

不幸的是,这不是很好。在参数列表中,空格可以在变量名中,并且在我的正则表达式中,不必要的逗号可以位于参数列表的和。对于这种情况,有人可以帮我正确使用正则表达式吗?提前谢谢!

2 个答案:

答案 0 :(得分:1)

事实上,我最近为函数头注释写了一个简单的正则表达式(为CS类自动格式化我的作业)。这是它的要点:

"def (\w+)\s*\((.*?)\):"

对于参数,我会放弃使用re,而是在捕获组str.split(',')上使用1。没有必要让它变得更加复杂。

答案 1 :(得分:0)

如果您可以导入功能定义,walk AST或使用inspect

如果您在签名旁边有更多解析,请考虑pyparsingfuncparselib

如果您仍然需要使用正则表达式,请耐心等待。

import re

# Python identifiers start with a letter or _,
#and continue with these or digits. 
IDENT = '[A-Za-z_][A-Za-z_0-9]*'

# Commas between identifiers can have any amout of space on either side.
COMMA = '\s*,\s*'

# Parameter list can contain some positional parameters.
# For simplicity we ignore now named parameters, *args, and **kwargs.
# We catch the entire list.
PARAM_LIST = '\((' + IDENT+'?' + '(?:' + COMMA+IDENT + ')*'+ ')?\)'

# Definition starts with 'def', then identifier, some space, and param list.
DEF = 'def\s+(' + IDENT + ')\s*' + PARAM_LIST

ident_rx = re.compile(IDENT)
def_rx = re.compile(DEF)


def test(s):
    match = def_rx.match(s)
    if match:
        name, paramlist = match.groups()
        # extract individual params
        params = [x.group() for x in ident_rx.finditer(paramlist or '')]
        print s, name, params 
    else:
        print s, 'does not match'

test('def foo(a, b)')
test('def foo()')
test('def foo(a,b,c , d,  e)')
test('deff foo()')
test('def foo(a, 2b)')

请注意,上面的代码无法使用默认值*args**kwargs或尾随逗号处理参数,更不用说Python {2}中的def foo(a, (b, c))合法内容了。这一切都可以补充说,但复杂性会飙升。

所以,除非你的情况相当简单(上面的代码示例是边界),请参阅上面的解析器链接。