给出以下(经过消毒的)输入:

Return_t
func()
{
  Type<SubType> cursorFeature(true);

  while (nDist < 800)
  {
    Result = Example(&var, 0, cursorFeature); //interested in this because inside loop, and not dereferenced or incremented
    if (!(++cursorFeature).NoMoreRecords())
    {
      if (!BLAH(blah)
        && (otherFunc(&var, &cursorFeature->derefenced, MACRO) != 0))
      {
        bIsChanged = true;
        break;
      }
      memcpy(&var, &cursorFeature->dereferenced, sizeof(anotherType_t));
    }
  }

  //more stuff
  }
}


我有以下正则表达式捕获使用Type后发生的循环

Type.*<.*>\s*(\w*)[^}]*?(?:while|for)\s*\(.*?\n?.*?(\{(?>[^{}]|(?-1))*\})


https://regex101.com/r/Kr0zQq/3

我还具有以下正则表达式,捕获了Type类型变量的特定用法:

Type.*<.*>\s*(\w*)[\s\S]*?\K(?<!\+\+)\1(?!->|\+\+)


https://regex101.com/r/Kr0zQq/4

我的目标是以某种方式将它们组合在一起,最好是合并到一个正则表达式中(如果可能的话,我也希望能够从VS内部进行此搜索)。鉴于递归正则表达式的性质,我不确定这是否有可能...而且我怀疑并非如此。如果不是这样,那么在搜索数百个文件时不会丢失文件名/数字上下文的聪明方法会很棒。我基本上需要文件名和行号。上下文很好,但不是必需的。

为了澄清起见,我想捕获cursorFeature,因为它的类型为Type,然后我想在"loop"{.....}中搜索它的用途。

编辑

只是有关我使用正则表达式解决此问题的说明。所搜索的代码超过一百万行,涵盖了由各种编译器编译并由多个构建系统构建的多个项目。而且,同时使用宏和高级语言功能意味着,即使是VS Intellisense也经常错误地解析VS能够编译的代码。和YCM(vim)一样。因此,可能有一个过度贪婪的正则表达式,它是70%的误报。 (由于在该循环中通常很容易扫描其余部分,因此缺少在循环内进一步使用变量的情况。)但是,尝试使用“通用” PCRE作为单行代码进行此操作可能是愚蠢的。 :)

最佳答案

您有三个选项可以查看以下循环中是否存在匹配的变量名。第一个是将(\1)添加到原子组并检查环境中此捕获组的存在(如果可能):

(?>(\1)|[^{}]|(?-2))*


其次,您可以通过使用负前瞻来缓和[^{}]的匹配过程:

(?>(?!\1)[^{}]|(?-1))*


但是如果您不像我在注释中提供的演示中那样将闭合括号设为可选,则失败。

第三,更好的解决方法是使用动词(*ACCEPT),该动词立即导致成功匹配结束,而无需在正则表达式中进行进一步更改:

(?>(\1)(*ACCEPT)|[^{}]|(?-2))*


Live demo

10-05 22:52
查看更多