这个正则表达式是否足以删除C ++多行注释?

时间:2009-10-16 11:51:08

标签: c++ regex parsing

我需要解析一些C ++文件,为了让事情变得更轻松,我考虑删除多行注释。我尝试了以下正则表达式:/(\/\*.*?\*\/)/,使用多线修改器,它似乎工作。你认为会有任何失败的情况吗?

4 个答案:

答案 0 :(得分:10)

以下情况会伤害你:

std::cout << "Printing some /* source code */" << std::endl;

这是一个很好的例子。想象一下,如果字符串开始发表评论并且没有结束,你可以做的损害?您最终可能会删除大量代码。

正则表达式可能会为您提供一个好的“快速而肮脏”的解决方案,并且可能适用于您的特定情况(我建议您在执行“删除”之前执行一次“提取并打印所有匹配”所有匹配“为了确保”,但在一般情况下,您将需要一个更复杂的解析器。你可以用正则表达式来解释这种情况,但它会变得丑陋。

编辑:感谢评论中的@MSalters,我意识到你所遇到的问题不仅仅涉及源文件,但严格来说,如果你使用带有嵌入式注释的宏,你会遇到麻烦。因此经过一些测试后发现,大多数机器上已经安装了一个工具,其中包含一个C ++编译器,可以清除注释,并为您处理所有棘手的字符串和宏问题。在file.cpp上使用此选项可以获得没有注释的输出(单行或多行):

cpp file.cpp

当然,这将扩展所有宏和#include,并且可能没有您想要的相同的漂亮整洁格式,但它将轻松处理与注释查找相关的所有宏,字符串和其他问题。如果您不知道,cpp是C预处理器作为独立的可执行文件(理论上,您可以使用#include#define等语言,使用类似C语言的任何语言),所以如果你没有它,你可以得到与GCC相同的效果:

gcc -E file.cpp

(如果您真的关心,请将gcc更改为g++ - 它可以更好地处理#include <iostream>。)

据我所知,删除注释并不是严格意义上的预处理器的一部分,但是大多数预处理器在那个阶段都是为了简化实际语言解析器的语法(嗯,GCC的预处理器就是这样,而且这就是我所拥有的)测试)。因此,如果您的编译器的预处理器选项将为您执行此操作,并且这就是您想要完成的任务,请立即停止自己的操作。

我很抱歉没有早点考虑这个问题。我不知道它是怎么逃过我的。

答案 1 :(得分:5)

另一个失败的例子:

//**** 
some code
/*
  comments
*/

在这种情况下,它将匹配除第一个斜杠之外的所有内容。

答案 2 :(得分:3)

正则表达式不能这样做。它只是不能。如果没有看到你写的内容,就很难说它是否正确地处理了所有的角落情况,但我的直接猜测是:“可能不会。”

举几个例子,考虑

// This is a single line\
comment

线条拼接仍然发生在评论中。还要记住,继续行的反斜杠可以从三字形创建:

// This is also a single-line??/
comment

您还必须确保不会尝试解析预处理程序语句,否则可能会遇到麻烦。例如,这可能包括指定目录中的所有标头:

#include <all_headers/*>

但如果你处理不当,你就是要把所有内容删除到下一个评论的末尾......

当然,为了保持有趣,也可以用三角形或有向图创建:

%:include <all_headers/*>

甚至是有向图和三字母的组合:

%:include<all_headers??/*>

在解决三字图之后,根本不包含注释分隔符,相当于:

#include <all_headers\*>

答案 3 :(得分:2)

没有尝试复活旧线程,但如果我遇到它,嘿!作为@Chris Lutz的g ++方法的更具体的答案:

g++ -fpreprocessed -E -P MyProgram.cpp -o NoComments.cpp

这将删除注释并更改空格,将新代码发送到“NoComments.cpp”,而不会显示其他所有内容。