1

我正在尝试使用正则表达式中的命名组来捕获方法调用的第一个参数。

例如给定:

.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>.+)(?=,|\),)
4

3 回答 3

4

以下应该有效:

\.MyMethod\((?<firstParam>(?:[^(),]*|\([^)]*\))+)[,)]

示例(和解释):http ://regex101.com/r/aS2uR9

请注意,这适用于您的所有测试用例,也适用于第一个参数的链式函数调用,但是如果您的第一个参数包含嵌套调用,例如.MyMethod(new MyObject(SomeOtherMethod())).

您可以通过使用此答案\([^)]*\)中的以下表达式替换部分来添加对任意嵌套括号的支持:

\((?>[^()]+|\((?<Depth>)|\)(?<-Depth>))*(?(Depth)(?!))\)
于 2013-06-13T19:04:23.483 回答
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);
}  
于 2013-06-13T18:58:58.753 回答
1

受此答案的启发:

\.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
于 2013-06-13T19:18:27.143 回答