2012-04-15 90 views
6

所有参数假设我有一个字符串,如下列:正则表达式匹配函数名和Python中

"func(arg1, arg2, arg3, arg4, ..., argn)" 

编辑:此功能无法在一些特定的语言。它只是有这种格式。如果它更容易,不要认为它是一个函数调用,只是一个字符串。

我想写一个正则表达式来匹配函数和每个的参数。我正在用Python写这个。这样做的期望输出是:

{"function" : "func", "arg" : ["arg1", "arg2", ... , "argn"]} 

编辑:尽管争论可能是函数调用,我可以很容易地递归地尝试用相同的正则表达式匹配他们一次我创建一个工程。通过这个我的意思是我可以在每个参数上对函数进行递归。但这不是真的有关。我是而不是试图创建一个解释器,只是用来识别参数。

这是我在这样的尝试:

import re 
s = "func(arg1, arg2, arg3, arg4, argn)" 
m = re.match(r"(?P<function>\w+)\s?\((?P<args>(?P<arg>\w+(,\s?)?)+)\)", s) 
print m.groupdict() 

这里是输出:

{'function': 'func', 'args': 'arg1, arg2, arg3, arg4, argn', 'arg': 'argn'} 

匹配功能就好了,所以做的参数设置。但是,我似乎无法匹配个别论点。这是我的正则表达式的问题,还是Python正则表达式匹配的限制?

EDIT2:我知道,我现在就可以使用下面的代码分裂的论点:

d["arg"] = d["args"].split(", ") 

但我在想,如果我可以用正则表达式完成整个工作。特别是,我想知道为什么“arg”仅与最后一个参数相匹配。 (1)希望弄清楚为什么Python每次只匹配最后一个参数,(2)我是否可以在Python中进行Scheme风格的模式匹配。或者,如果在Python中有与Scheme-style模式匹配一​​样直观的东西。我查看了ast模块,其语法非常复杂。

+1

这个函数调用某种特定的语言吗?你不应该使用正则表达式来解析已经存在正确/完整解析器的语言...... – Borealid 2012-04-15 17:04:49

+0

你不能用正则表达式来做到这一点(假设你想匹配单个参数,它们本身可能是函数调用)。你需要一个实际的解析器。如果你坚持写你自己的,然后阅读:http://effbot.org/zone/simple-iterator-parser.htm – Wes 2012-04-15 17:12:13

+0

你可能想签出[pyparsing](http://pyparsing.wikispaces.com/ )如果你打算做更复杂的事情。 – 2012-04-15 17:20:27

回答

4

看起来像你90%在那里,为什么不直接交换argargs分组和做到:

import re 

fn_match = re.match(r"(?P<function>\w+)\s?\((?P<arg>(?P<args>\w+(,\s?)?)+)\)", s) 
fn_dict = fn_match.groupdict() 
del fn_dict['args'] 
fn_dict['arg'] = [arg.strip() for arg in fn_dict['arg'].split(',')] 
+0

我试图捕获整个事情作为正则表达式。这不可能吗? – BlackSheep 2012-04-15 19:13:50

+0

不要得到所需的参数列表。为什么只有瑞士军刀,当你有一个整体工具箱? – mVChr 2012-04-15 21:40:27

7

正则表达式无法分析复杂的编程语言。

如果你只是想解析Python,我建议看看ast模块,它会为你解析它。

+0

我不想解析Python,只是捕获一个非常特定的语法。从我阅读的小部分来看,似乎ast模块是(1)专用于Python的,(2)对于我正在尝试做的事情来说非常复杂。 – BlackSheep 2012-04-15 19:35:38

1

要回答你的问题的最后一部分:第Python没有类似的东西Scheme的“匹配”,也没有像ML/Haskell那样的模式匹配。它最接近的是解构这样的事情

>>> (a, [b, c, (d, e)]) = (1, [9, 4, (45, 8)]) 
>>> e 
8 

并提取列表的头和尾(在Python 3.X)这样的能力...

>>> head, *tail = [1,2,3,4,5] 
>>> tail 
[2, 3, 4, 5] 

虽然有一些模块在python中进行实模式匹配,但我无法保证它们的质量。

如果我必须这样做,我会实现它有点不同 - 也许有能力输入一个类型和可选参数(如长度或确切的内容)和一个函数来调用,如果它匹配匹配([list,length = 3,check =(3,str),func])并且匹配(list _ _ somestr)并且在范围内调用func和somestr,还可以添加更多模式。