2012-04-14 14 views
1

私は単純なpython関数のシグネチャに一致するpython正規表現を書こうとします。 ように:Python関数の署名のためのPython正規表現

def _func1_(arg1, arg2): 

私はこの正規表現を作成しました:

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

は残念ながら、これは本当に良いではありません。引数リストでは、空白は変数名の中にあり、不要なコンマは正規表現の引数リストとにあります。誰かがこのケースの正しい正規表現で私を助けることができますか?前もって感謝します!

+3

正規表現はパーサーではありません。 –

+1

[ASTを歩く](http://docs.python.org/dev/library/ast.html)はなぜですか? –

+0

末尾のカンマは実際にはPythonによって許可されています。 – 9000

答えて

1

実際に、私は最近、関数ヘッダーコメント用の単純な正規表現を書いています(CSクラスの宿題を自動的にフォーマットするため)。ここでの要点です:

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

パラメータの場合は、私が再を使用して断念し、代わりにキャプチャグループ1str.split(',')を使用します。必要以上に複雑にする必要はありません。

+1

'def fn(a =(1,2)):'は有効な定義です。もっと複雑にする必要があります。 –

+0

@ IgnacioVazquez-Abrams:どの部分?私の答えの '再 '部分はまだ完全に正常に動作します。しかし、 'a =(1,2)'に 'split("、 ")'を使ってどのように壊れるかを見ることができます。 –

+0

@Ignacio:申し訳ありませんが、忘れてしまいましたが、私の仕事は簡単です。引数リストには、私の例のような単純な変数名しか含めることができません。 – WonderCsabo

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))このすべてのようなおろかなものを追加することができますが、複雑さが急上昇します。

あなたのケースがかなり単純でない限り(上のコード例は境界線です)、上のパーサーリンクを参照してください。