1

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

def _func1_(arg1, arg2):

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

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

不幸的是,这并不是很好。在参数列表中,空格可以在变量名中,不必要的逗号可以在参数列表的 and 处,在我的正则表达式中。有人可以帮我解决这个案例的正确正则表达式吗?提前致谢!

4

2 回答 2

2

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

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

对于参数,我会放弃使用 re 而是使用str.split(',')on capture group 1。没有必要让它变得比它必须的更复杂。

于 2012-04-15T00:13:48.973 回答
0

如果您可以导入函数定义,请使用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,或尾随逗号,更不用说def foo(a, (b, c))Python 2 中的合法性了。这一切都可以添加,但复杂性会飙升。

因此,除非您的情况相当简单(上面的代码示例是临界的),否则请参阅上面的解析器链接。

于 2012-04-15T02:52:22.993 回答