Removing C comments FAQ

[email protected] (karl williamson) Tue, 14 Feb 2006 10:29:12 -0700
Newsgroups perl.perlfaq.workers
Message-ID <[email protected]>
There is a RE in the FAQ for removing C comments.  It appears to me that 
part of it is unnecessarily complicated by not using the non-greedy 
quantifiers.

I looked at the re and struggled trying to figure out what I was 
missing, why was the part that matched the actual C comment so 
complicated?  I looked around on the internet, and found similar 
expressions, written for languages, unlike perl, which have only greedy 
quantifiers.

I believe that in the faq, this answer could be replaced by the 
attachment (which I have barely tested).  Here is the code of the 
attachment, but email will have put in extra line breaks:


     $/ = undef;
     $_ = <>;
     s#/\*.*?\*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $1 
? $1 : ""#gse;
     print;

This could, of course, be more legibly written with the /x modifier, 
adding whitespace and comments. Here it is expanded, courtesy of Fred 
Curtis.

     s{
        /\*.*?\*/         ##  /* ... */ comment
      |         ##     OR  various things which aren't comments:

        (
          "           ##  Start of " ... " string
          (
            \\.           ##  Escaped char
          |               ##    OR
            [^"\\]        ##  Non "\
          )*
          "           ##  End of " ... " string

        |         ##     OR

          '           ##  Start of ' ... ' string
          (
            \\.           ##  Escaped char
          |               ##    OR
            [^'\\]        ##  Non '\
          )*
          '           ##  End of ' ... ' string

        |         ##     OR

          .           ##  Anything other char
          [^/"'\\]*   ##  Chars which doesn't start a comment, string or 
escape
        )
      }{defined $1 ? $1 : ""}gxse;

A slight modification also removes C++ comments:

 
s#/\*.*?\*/|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined 
$1 ? $1 : ""#gse;
fix (text/plain, 1.2 KB)
    $/ = undef;
    $_ = <>;
    s#/\*.*?\*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $1 ? $1 : ""#gse;
    print;

This could, of course, be more legibly written with the /x modifier, adding whitespace and comments. Here it is expanded, courtesy of Fred Curtis.

    s{
       /\*.*?\*/         ##  /* ... */ comment
     |         ##     OR  various things which aren't comments:

       (
         "           ##  Start of " ... " string
         (
           \\.           ##  Escaped char
         |               ##    OR
           [^"\\]        ##  Non "\
         )*
         "           ##  End of " ... " string

       |         ##     OR

         '           ##  Start of ' ... ' string
         (
           \\.           ##  Escaped char
         |               ##    OR
           [^'\\]        ##  Non '\
         )*
         '           ##  End of ' ... ' string

       |         ##     OR

         .           ##  Anything other char
         [^/"'\\]*   ##  Chars which doesn't start a comment, string or escape
       )
     }{defined $1 ? $1 : ""}gxse;

A slight modification also removes C++ comments:

    s#/\*.*?\*/|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $1 ? $1 : ""#gse;