这是我的字符串:
SELECT x FROM Table1 WHERE (SELECT y FROM Table2 LIMIT 1) > 15 LIMIT 4
这是我的正则表达式:
SELECT .+ FROM .+ LIMIT (?<LIMITCOUNT>\d{1,4})
我希望它进行 2 次捕获;一个是整个字符串,另一个是括号中的部分,但它只捕获整个字符串。我的出路是什么?
您可以在前瞻中捕获它
(?=((?<=^|\s)SELECT .+? LIMIT \d{1,4}(?=\s|$)|(?<=\()SELECT .+? LIMIT \d{1,4}(?=\))))
这将在您的示例中捕获 2 个查询!使用组 1 访问它
在这里试试
我明白你在这里的意思。当您调用Matches
以获取多个匹配项时,它不会搜索“在”其他匹配项中的匹配项;它找到第一个匹配项,然后在该匹配项结束后再次开始查找,依此类推。
我不相信有一种开箱即用的方式来做你想做的事,所以你需要手动完成。您需要进行一些更改:
.+
非贪婪 ( .+?
)FROM
匹配第一个FROM
,而不是第二个。目前它与第二个匹配FROM
,这弄乱了第 2 步:.+
,例如(?<PotentialNested>.+)
。保持贪婪,以便LIMIT
匹配第二个LIMIT
,而不是第一个。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>\))|[^()]*)+)