【发布时间】:2018-04-23 19:04:17
【问题描述】:
鉴于以下(已清理)输入:
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
我的目标是以某种方式将这些组合起来,最好是 ONE 正则表达式(如果可能的话,我也希望能够在 VS 中进行此搜索)。鉴于递归正则表达式的性质,我不确定这是否可能......我怀疑它不是。如果没有,那么在搜索数百个文件时不会丢失文件名/数字上下文的聪明东西会很棒。我基本上需要文件名和行号。上下文很好,但不是必需的。
为了澄清,我想捕获cursorFeature,因为它的类型是Type,然后我想在"loop"{.....}中搜索它的使用
编辑
只是关于我使用正则表达式来解决这个问题的说明。正在搜索的代码超过一百万行,跨越由各种编译器编译并由多个构建系统构建的多个项目。并且同时使用宏和高级语言功能意味着,例如,即使 VS Intellisense 经常错误解析代码 VS 也能够编译。 YCM(vim)也是如此。所以,一个 70% 误报的可能过于贪婪的正则表达式是可以的。 (因为在循环中缺少变量使用的进一步发生,因为此时通常很容易扫描其余部分。)但是,尝试使用“通用”PCRE 作为单行执行此操作可能是愚蠢的。 :)
【问题讨论】:
-
如果这个问题有什么不清楚的地方,我会全力以赴。我试图尽可能具体。
-
有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。 -- Jamie Zawinski(署名)
-
这里的问题是,正则表达式对于这项任务来说是完全错误的工具。您需要一个真正的解析器,而正则表达式将永远无法处理所有可能的情况。即使您让它工作,它也会中断其他输入,并且必须维护它的人,如果他们有任何经验,将把它扔掉并用解析器替换它。
-
另一个想法。你不需要一个完整的解析器,只需要一个能够找到你需要的东西。不要使用单个正则表达式,编写 Perl 代码一次解析一行,这应该更容易。
-
您最好尽可能避免使用贪婪的点量词。将此regex101.com/r/fxWtAF/2 与您的进行比较。
标签: c# regex visual-studio perl