C++ 正确解析正则表达式中的注释

C++ 正确解析正则表达式中的注释,c++,c,regex,C++,C,Regex,我正在创建一个编译器,在处理多行注释时遇到问题(/**/)。问题是我的正则表达式需要修复。我认为它所做的是查找开始注释标记(/*),但会接受任何结束注释标记(*/),这些标记甚至可能不属于注释范围 另一个问题是,在一个字符串中,它仍然会尝试注释掉它。这个问题我还没有实施,但一些帮助将不胜感激 我使用的正则表达式是: [/][*](.|\n)*[*][/] 示例: 输入: int main(/* text */) { int i = 0; /* hello world */ r

我正在创建一个编译器,在处理多行注释时遇到问题
(/**/)
。问题是我的正则表达式需要修复。我认为它所做的是查找开始注释标记(
/*
),但会接受任何结束注释标记(
*/
),这些标记甚至可能不属于注释范围

另一个问题是,在一个字符串中,它仍然会尝试注释掉它。这个问题我还没有实施,但一些帮助将不胜感激

我使用的正则表达式是:

[/][*](.|\n)*[*][/]
示例:

输入:

int main(/* text */) {
   int i = 0;
   /* hello world */
   return 1;
} 
输出:

int main(

   return 1;
} 
然后对于字符串,输入为:

 int main() {
       printf("/* hi there */\n");
       return 1;
    } 
\/\*.*?\*\/
输出:

int main() {
      printf("\n");
       return 1;
} 

我不确定您使用的是什么正则表达式库,但您需要所谓的非贪婪匹配

试试这个:

\/\*(.|\n)*?\*\/
*
之后的
使匹配取消冻结

你可以想象这是如何工作的

请注意,这是语法,我假设您正在使用。如果您使用的是POSIX正则表达式,这将不起作用

您也不需要将
/
*
放入字符类(
[…]
)中;你只需要逃离他们

您还可以使用
PCRE\u DOTALL
标志使
匹配
\n
\r
,这可以简化正则表达式

PCRE_DOTALL
   If  this bit is set, a dot metacharacter in the pattern matches a char-
   acter of any value, including one that indicates a newline. However, it
   only  ever  matches  one character, even if newlines are coded as CRLF.
   Without this option, a dot does not match when the current position  is
   at a newline. This option is equivalent to Perl's /s option, and it can
   be changed within a pattern by a (?s) option setting. A negative  class
   such as [^a] always matches newline characters, independent of the set-
   ting of this option.
那么,将是:

 int main() {
       printf("/* hi there */\n");
       return 1;
    } 
\/\*.*?\*\/
您还可以使用
PCRE\u ungreedy
标志使整个regex ungreedy:

PCRE_UNGREEDY

   This option inverts the "greediness" of the quantifiers  so  that  they
   are  not greedy by default, but become greedy if followed by "?". It is
   not compatible with Perl. It can also be set by a (?U)  option  setting
   within the pattern.
在这种情况下,:


正则表达式对于编译器来说并不是很好。如果您对C语法的分析足以处理转义换行符、字符常量、字符串文本和单行注释,Will为使用锚定多行注释提供了一个很好的解决方案。您不能依靠正则表达式一次从完整的C源文件中删除注释。为完整起见,请注意
/
*
可以使用转义换行符在两行上拆分。我们可以匹配
\/(\\[\n])?\*
。我同意regex不是一个好方法,但在我看来,这是一个regex问题,而不是解析c-comments问题:)我可能会逐个字符检查字符串。但是,尽管如此,这还是一个学习regex的好机会。我完全同意。我将提出对问题本身的评论,你的回答很好。