编写 C++ 正则表达式来匹配 #include 预处理指令

SEA*_*unt 2 c++ regex include

我想用 C++ 编写一个正则表达式来匹配 #include 预处理指令。所以我写了这个:

std::regex includePattern("^[[:blank:]|[:space:]]*#[[:blank:]|[:space:]]*include[[:blank:]|[:space:]]+[<|\"]{1}[_[:alpha:]]+[_[:alnum:]]*");
Run Code Online (Sandbox Code Playgroud)

这适用于:

std::string matchString = "#include <vector>";
Run Code Online (Sandbox Code Playgroud)

但仅匹配字符串的一部分,排除了尾随的“>”,但如果我将正则表达式更改为:

std::regex includePattern("^[[:blank:]|[:space:]]*#[[:blank:]|[:space:]]*include[[:blank:]|[:space:]]+[<|\"]{1}[_[:alpha:]]+[_[:alnum:]]*[>|\"]{1}");
Run Code Online (Sandbox Code Playgroud)

它只是不会给我想要的结果,只是告诉我“未找到”!有什么不对的吗?

任何人都可以帮助我在 c++ 中编写准确的正则表达式来匹配 #include 预处理指令吗?

提前致谢!

Jam*_*nze 5

取决于要匹配的输入是否可能包含换行符? [[:space:]]将匹配任何空白,包括新行,[[:blank:]]将匹配除新行之外的任何空白(我不确定标准是否支持它)。无论如何,类似:

"^\\s*#\\s*include\\s+[<\"][^>\"]*[>\"]\\s*"
Run Code Online (Sandbox Code Playgroud)

应该可以解决问题,但是...

  • 如果您的源代码在不应该出现的地方出现了新行,它仍然可能匹配。

  • 如果您的源已转义新行,例如在标记或文件名的中间include,则它将不匹配。(这是合法的 C++,但没有一个头脑正常的人会这么做。)

  • 如果您的源有不匹配的分隔符("一端为 a,另一端为a<或 a ),它仍然会匹配。<

  • 并且它不处理行尾的注释。处理 C++ 风格的注释 ( ) 应该只是添加到表达式末尾//的问题 。"(?://.*)?"处理 C 风格的注释(特别是因为可能有多个)有点复杂。

为了确保分隔符匹配,您可能必须将包含后的所有内容放在 or 中:

"^\\s*#\\s*include\\s+(?:<[^>]*>|\"[^\"]*\")\\s*"
Run Code Online (Sandbox Code Playgroud)

同样,您需要添加到末尾来处理评论。