1

正規表現で名前付きグループを使用して、メソッド呼び出しの最初のパラメーターを取得しようとしています。

例:

.MyMethod(foo);
.MyMethod(foo, bar);
.MyMethod(new MyObject(1, 2), 3);
.MyMethod(new MyObject()).MyChainedMethod();

名前付きグループのパターンが返されます。

foo
foo
new MyObject(1, 2)
new MyObject()

さまざまな組み合わせを試しましたが、すべてのケースに一致するわけではありません。たとえば、次の例は 2 番目と 3 番目のケースに一致します。

\.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 に答える