0

これが私の文字列です:

SELECT x FROM Table1 WHERE (SELECT y FROM Table2 LIMIT 1) > 15 LIMIT 4

これが私の正規表現です:

SELECT .+ FROM .+ LIMIT (?<LIMITCOUNT>\d{1,4})

2回のキャプチャを実行したい。1つはストリング全体で、もう1つはパランセシスの一部ですが、ストリング全体のみをキャプチャします。私の方法は何ですか?

4

2 に答える 2

0

先読みでキャプチャできます

(?=((?<=^|\s)SELECT .+? LIMIT \d{1,4}(?=\s|$)|(?<=\()SELECT .+? LIMIT \d{1,4}(?=\))))

これにより、例で2つのクエリがキャプチャされます!グループ1を使用してアクセスします

ここで試してみてください

于 2013-01-18T08:15:47.510 に答える
-1

ここで何が得られているかわかります。複数の一致を取得するために呼び出す場合Matches、他の一致の「範囲内」の一致は検索されません。最初の一致を見つけて、その一致の終了後に再度検索を開始します。

すぐに使える方法でやりたいことがあるとは思わないので、手動で行う必要があります。いくつかの変更を加える必要があります。

  1. 最初.+の貪欲でない(.+?)を作成して、2番目ではなくFROM最初のに一致するようにしFROMます。現時点では2番目FROMと一致しており、これによりステップ2が台無しになります。
  2. .+2番目の周り​​に別のキャプチャグループを追加します(?<PotentialNested>.+)。貪欲に保ち、最初ではなくLIMIT2番目に一致するようにします。LIMIT
  3. 最初の文字列の一致をチェックした後、これらのPotentialNestedキャプチャをさらに一致するかどうかを再帰的にチェックし続けるメソッドを記述します。
public static IEnumerable<Match> NestedMatches(this Regex regex, string input)
{
    var potentialNested = new Queue<string>();
    foreach (Match m in regex.Matches(input))
    {
        yield return m;
        potentialNested.Enqueue(m.Groups["PotentialNested"].Value);
    }
    while (potentialNested.Count > 0)
    {
        foreach (Match m in regex.Matches(potentialNested.Dequeue()))
        {
            yield return m;
            potentialNested.Enqueue(m.Groups["PotentialNested"].Value);
        }
    }
}

編集:実際には、このすべての後、2つのネストされた用語が隣り合っている場合は、それでも機能しません。

SELECT x FROM Table1 WHERE
((SELECT y FROM Table2 LIMIT 1) + (SELECT y FROM Table2 LIMIT 1)) > 15
LIMIT 4

これが潜在的な入力である場合は、PotentialNestedキャプチャグループがブラケットのバランスをとっていることを確認してみてください。

(?<PotentialNested>((?<BR>\()|(?<-BR>\))|[^()]*)+)
于 2013-01-18T08:36:59.113 に答える