我使用的是 Visual Studio、C++。我想确保大类(称为ExampleClass)中的每个函数都以调用宏(EXAMPLE_MACRO();)开始。
我想我可以通过使用这个正则表达式来做到这一点:
ExampleClass::[\s\S]*?{\s*\n\s*(?!.*EXAMPLE_MACRO)
不幸的是,当函数中除了第一个字符之外还有其他“{”字符时,正则表达式会将函数注册为匹配项。
有人对我如何解决这个问题有任何想法吗?以下是一些用于测试的示例函数...
bool ExampleClass::ExampleFunction1(
const bool ExampleParam) const
{
// No macro call, this should be a match.
}
void ExampleClass::ExampleFunction2(const bool ExampleParam)
{
EXAMPLE_MACRO();
// Macro call exists, this should NOT be a match.
if()
{
}
}
bool ExampleClass::ExampleFunction3(
const bool ExampleParam1,
const bool ExampleParam2)
{
EXAMPLE_MACRO();
// Macro call exists, this should NOT be a match.
}
一些问题:
[\s\S]*?
可以在其匹配中包含 {
字符。当正则表达式由于否定前瞻断言不正确而必须回溯时,可能会发生这种情况。相反,您最好明确禁止{
。由于输入似乎是 C++ 代码,还要考虑没有主体的方法声明:您可能不希望匹配交叉到下一个方法声明,并使用 ;
也禁止 [^{;]*
。
\s*\n\s*
可能会导致无用的回溯,因为 \n
也与 \s
匹配。此外,由于 C++ 代码不需要这些换行符,因此您不应在此处需要它们。只需使用\s*
。
.*
中的(?!.*EXAMPLE_MACRO)
也可以包含左大括号——如果源代码没有使用换行符来很好地格式化代码。相反,要求这些字符都是空白。
EXAMPLE_MACRO
也会匹配 EXAMPLE_MACRO_WITH_MORE_TEXT
这可能不是您想要的,所以请确保也匹配左括号。
某些正则表达式风格要求必须转义左大括号(用作文字字符)。无论如何,这样做并没有什么坏处,而且在没有歧义的情况下不需要这样做。
更正如下:
ExampleClass::[^{]*\{(?!\s*EXAMPLE_MACRO\s*\()
注意局限性。这测试了
EXAMPLE_MACRO(
不会立即出现在带有可选空白的左大括号之后。如果左大括号后面恰好跟着 /*
或 //
(表示注释),则不会检查 EXAMPLE_MACRO(
是否仍可能跟在该注释之后。