正则表达式找到一个有点递归的模式

时间:2013-01-18 08:02:05

标签: c# .net regex

这是我的字符串:

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

这是我的正则表达式:

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

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

2 个答案:

答案 0 :(得分:0)

您可以在前瞻中捕获它

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

这将在您的示例中捕获2个查询!使用组1访问它

试试here

答案 1 :(得分:-1)

我知道你在这里得到了什么。当您致电Matches以获得多个匹配项时,它不会在其他匹配项中搜索匹配项;它找到第一个匹配,然后在该匹配的结束之后再次开始查找,依此类推。

我不相信有一种开箱即用的方式来做你想做的事情,所以你需要手动完成。你需要做一些改变:

  1. 让您的第一个.+非贪婪(.+?),以便FROM与第一个FROM匹配,而不是第二个FROM。目前它与第二个.+相匹配,这就是第二步:
  2. 在第二个(?<PotentialNested>.+)周围添加另一个捕获组,例如LIMIT。请保持贪婪,以便LIMIT与第二个PotentialNested匹配,而不是第一个。{/ li>
  3. 编写一个方法,在检查匹配的初始字符串后,继续检查这些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); } } } 捕获以进一步匹配,递归:
  4. SELECT x FROM Table1 WHERE
    ((SELECT y FROM Table2 LIMIT 1) + (SELECT y FROM Table2 LIMIT 1)) > 15
    LIMIT 4
    

    编辑:实际上,在所有这些之后,如果您有两个彼此相邻的嵌套术语,它仍然无效,例如

    PotentialNested

    如果这是潜在的输入,您可以尝试确保您的(?<PotentialNested>((?<BR>\()|(?<-BR>\))|[^()]*)+) 捕获组平衡括号:

    {{1}}