0

这是我的字符串:

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

这是我的正则表达式:

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

我希望它进行 2 次捕获;一个是整个字符串,另一个是括号中的部分,但它只捕获整个字符串。我的出路是什么?

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. 使您的第一个.+非贪婪 ( .+?)FROM匹配第一个FROM,而不是第二个。目前它与第二个匹配FROM,这弄乱了第 2 步:
  2. 在您的第二个周围添加另一个捕获组.+,例如(?<PotentialNested>.+)。保持贪婪,以便LIMIT匹配第二个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);
        }
    }
}

编辑:实际上,毕竟,如果您有两个相邻的嵌套术语,它仍然不起作用,例如

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 回答