假设我有一个var std::string sourceCode;
,我已经加载了一个cpp源文件。现在我想删除tr1中包含的正则表达式类的所有注释(现在它们完全包含在我使用Microsoft编译器中) - 单行很容易但不是多行。它不仅仅是用空格等替换注释,而是要保持正确的行数。假设我们删除了5行长的注释,然后应该用5个换行符填充此空格,以便我能够回溯代码并使用正确的行号进行计算。
到目前为止我的代码:
std::regex singleLinedCommentReg("//.*");
sourceCode = std::regex_replace(sourceCode, singleLinedCommentReg, std::string(""));
std::regex multiLinedCommentReg("(/\\*([^*]|[\r\n]|(\\*+([^*/]|[\r\n])))*\\*+/)");
std::for_each(
std::sregex_iterator(sourceCode.begin(), sourceCode.end(), multiLinedCommentReg),
std::sregex_iterator(),
[&](const std::match_results<std::string::const_iterator>& match) -> bool {
// TODO: Replace the current match with an appropriate number of newlines.
return true;
}
);
有人可以给我一些建议吗?
编辑#1
我 NOT 想要引发关于讨论的评论是否有意义使用RegEx进行此类操作!请假设输入是干净的并且符合预期。
答案 0 :(得分:4)
使用正则表达式的方法很简单,太复杂了。您正在尝试使用常规语言(正则表达式)来解析至少与无上下文语法一样复杂的情况。如果你拆分并用C ++完成部分处理,你就可以完成它,但它看起来很混乱。
如果您的目标是编写一个删除所有注释而不会丢失新行字符的函数,我建议您使用许多可用的解析工具之一生成解析。
这需要不到5分钟的时间来创建,而且功能正是您所需要的。您可以根据自己的心灵内容进行修改。它将生成flex 2.5.4或flex 2.5.35
的词法分析器%{
#include <stdio.h>
%}
cbeg "/*"
cend "*/"
cppc "//"
nl "\n"|"\r\n"
%option noyywrap
%x mlc
%%
{nl} { fputs(yytext, stdout); }
{cbeg} { BEGIN(mlc); }
{cend} { fprintf(stderr, "Error: found end of comment without a beginning\n"); return -1; }
{cppc}.* /* eat up the comment */
. { fputs(yytext, stdout); }
<mlc>{cend} { BEGIN(INITIAL); }
<mlc>{cbeg} { fprintf(stderr, "Error: Found /* inside another /* comment"); return -1; }
<mlc>. /* eat up everything else */
%%
int main(int argc, char* argv[])
{
yylex();
}
附录:
以上是一个功能齐全的计划。您可以使用:
生成.cflex -t foo.l > foo.c
你可以用
编译它cc -o foo foo.c
现在像
./foo < source.c > source-sans-comments.c
将生成新的源文件。
答案 1 :(得分:0)
最好的方法是使用两个regexen。第一个将删除所有单行注释(这些不会影响行号)。
然后,使用另一个正则表达式删除多行注释,并循环遍历每个注释,直到不再有:
regex mlc("\\/\\*[^(\\/\\*)]*?\\*\\/");
string data = something;
match_results<std::string::const_iterator> searchresult;
while (regex_search(data, searchresult, mlc)) {
const string& match = searchresult.str();
auto newlinecount = std::count(match.begin(), match.end(), '\n');
data.replace(searchresult.position(), match.length(), newlinecount, '\n');
}