我尝试编写一个python正则表达式,它匹配简单python函数的签名。 像:
def _func1_(arg1, arg2):
我创建了这个正则表达式:
"def ([^\W\d]+\w*)(\(( *[^\W\d]+\w* *,? *)*\)):"
不幸的是,这不是很好。在参数列表中,空格可以在变量名中,并且在我的正则表达式中,不必要的逗号可以位于参数列表的和。对于这种情况,有人可以帮我正确使用正则表达式吗?提前谢谢!
答案 0 :(得分:1)
事实上,我最近为函数头注释写了一个简单的正则表达式(为CS类自动格式化我的作业)。这是它的要点:
"def (\w+)\s*\((.*?)\):"
对于参数,我会放弃使用re,而是在捕获组str.split(',')
上使用1
。没有必要让它变得更加复杂。
答案 1 :(得分:0)
如果您可以导入功能定义,walk AST或使用inspect。
如果您在签名旁边有更多解析,请考虑pyparsing或funcparselib。
如果您仍然需要使用正则表达式,请耐心等待。
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))
合法内容了。这一切都可以补充说,但复杂性会飙升。
所以,除非你的情况相当简单(上面的代码示例是边界),请参阅上面的解析器链接。