我尝试使用正则表达式中的命名组捕获方法调用的第一个参数。
E.g。给出:
.MyMethod(foo);
.MyMethod(foo, bar);
.MyMethod(new MyObject(1, 2), 3);
.MyMethod(new MyObject()).MyChainedMethod();
应该为指定的组返回模式:
foo
foo
new MyObject(1, 2)
new MyObject()
我尝试了各种组合,但不能匹配每个案例,例如以下内容与第二个和第三个案例相匹配:
\.MyMethod\((?<firstParam>.+)(?=,|\),)
答案 0 :(得分:4)
以下内容应该有效:
\.MyMethod\((?<firstParam>(?:[^(),]*|\([^)]*\))+)[,)]
示例(和说明):http://regex101.com/r/aS2uR9
请注意,这适用于所有测试用例,并且还可以使用第一个参数的链接函数调用,但是如果第一个参数包含嵌套调用,则它将不起作用,例如.MyMethod(new MyObject(SomeOtherMethod()))
。
您可以使用this answer中的以下表达式替换\([^)]*\)
部分来添加对任意嵌套括号的支持:
\((?>[^()]+|\((?<Depth>)|\)(?<-Depth>))*(?(Depth)(?!))\)
答案 1 :(得分:2)
你做不到。正则表达式不能计算括号,因此您将无法验证打开的括号数是否与已关闭的括号匹配。这是正则表达式的限制,因为它们不能递归。
构建自己的解析方法并遍历字符串。也许:
string Parse(string str) {
int open = 0;
bool started = false;
int begin;
for(int x = 0; x < str.length && (open > 0 || !started); x++) {
char tok = str[x];
if (started && tok == '(') open++;
if (started && tok == ')') open--;
if (!started && tok == '(') { started = true; open++; begin = x+1; }
}
assert(begin < str.length && open == 0);
return str.substring(begin, x - begin);
}
答案 2 :(得分:1)
灵感来自this answer:
\.MyMethod\((?<firstParam>(?:[^(,]|(?<brackets>\()|(?<-brackets>\))|(?(brackets),))*)(?:\)|,)
这是一个复杂的正则表达式,当正则表达式花了很长时间才开始研究Jean-Bernard Pellerin提供的专用解析方法。
工作原理:
\.MyMethod\( Basic Text Match for .MyMethod(
(?<firstParam> Capturing group
(?:[^(,] Not a bracket or comma
|(?<brackets>\() Or a opening bracket that is added to the
brackets capturing group
|(?<-brackets>\)) Or a closing bracket that removes an item
from the brackets capturing group (failing
if there are no items to remove)
|(?(brackets),))*) Or if we have reached a lower level a comma
(?:\)|,) closing bracket or comma