QRegExp用于从代码中提取单行注释

时间:2013-07-04 11:06:38

标签: c++ regex qt qregexp

我必须从qmake项目文件中提取单行注释。 规则很简单:评论以#符号开头,以换行符\n开头。 所以我读了一些关于QRegExp的文档,并编写了这样的代码来打印qmake文件中的所有注释:

QRegExp re ("#(.*)\n$");
re.setMinimal (true);
int comment_index = 0;
while ((comment_index = _project_contents.indexOf (comment_expr, comment_index)) != -1)
{
    QString comment_text = comment_expr.cap (0);
    qDebug() << "Comment 1" << comment_text;
}

但它无法正常工作 - 只打印了项目文件的所有内容。 我的错误在哪里?正如我从文档中理解的那样,这应该有效,但事实并非如此。

P.S。我是正则表达式的新手,所以请不要打败我:)

1 个答案:

答案 0 :(得分:2)

问题在于. "matches any character (including newline)."。而$是字符串的结尾。

您可以尝试使用not-newline - [^\n]并将$更改为(\n|$)(换行符或字符串结尾):

"#[^\n]*(\n|$)"

但是这会匹配#在任何地方,而不仅仅是在一行的开头,所以让我们试试这个:

"(^|\n)#[^\n]*(\n|$)"

^是字符串的开头,所以基本上(^|\n)(字符串或新行的开头)就在行开头之前。

你能看到问题吗?如果连续2行有2条评论怎么办?你只会匹配第一个,因为在第一个匹配期间会消耗换行(因为下一个匹配从前一个匹配完成开始)。

解决此问题的方法是使用预测:

"(^|\n)#[^\n]*(?=\n|$)"

这会导致结束换行符不包含在匹配中(但仍会检查),因此位置将位于换行符之前,下一个匹配项可以使用它。

#可以以空格开头吗?如果是,请检查零个或多个空格(\s*):

"(^|\n)\s*#[^\n]*(?=\n|$)"