Как я могу удалить многострочные комментарии C из файла, используя Perl? - PullRequest
5 голосов
/ 18 мая 2009

Может кто-нибудь заставить меня использовать регулярное выражение для удаления многострочных комментариев и однострочных комментариев в файле?

например:

                  " WHOLE "/*...*/" HAS TO BE STRIPED OFF....."

1.   /* comment */
2.   /* comment1 */  code   /* comment2 */ #both /*comment1*/ and /*comment2*/ 
                                             #has to striped off and rest should 
                                                 #remain.
3.   /*.........
       .........
       .........
       ......... */

Я очень ценю тебя, если ты сделаешь это ... спасибо заранее.

Ответы [ 6 ]

16 голосов
/ 26 мая 2009

From perlfaq6"Как использовать регулярное выражение для удаления комментариев в стиле C из файла?":


Хотя это на самом деле можно сделать, это гораздо сложнее, чем вы думаете. Например, этот однострочный

perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c

будет работать во многих, но не во всех случаях. Видите ли, он слишком прост для некоторых видов программ на C, в частности, для тех, которые выглядят как комментарии в строках в кавычках. Для этого вам понадобится что-то вроде этого, созданное Джеффри Фридлом и позднее измененное Фредом Кертисом.

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

Конечно, это может быть написано более четко с помощью модификатора / x, с добавлением пробелов и комментариев. Здесь это расширено, любезно предоставлено Фредом Кертисом.

s{
   /\*         ##  Start of /* ... */ comment
   [^*]*\*+    ##  Non-* followed by 1-or-more *'s
   (
     [^/*][^*]*\*+
   )*          ##  0-or-more things which don't start with /
               ##    but do end with '*'
   /           ##  End of /* ... */ 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 $2 ? $2 : ""}gxse;

Небольшая модификация также удаляет комментарии C ++, возможно, занимая несколько строк, используя символ продолжения:

 s#/\*[^*]*\*+([^/*][^*]*\*+)*/|//([^\\]|[^\n][\n]?)*?\n|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $3 ? $3 : ""#gse;
11 голосов
/ 18 мая 2009

Как часто в Perl, вы можете обратиться к CPAN: Regexp :: Common :: Comment должен вам помочь. Единственный язык, который я нашел и использует комментарии, которые вы описали, это Nickle, но, возможно, комментарии PHP будут в порядке (// также можно начинать однострочный комментарий).

Обратите внимание, что в любом случае использование регулярных выражений для удаления комментариев опасно, полный синтаксический анализатор для языка гораздо менее рискован. Например, анализатор регулярных выражений может запутаться чем-то вроде print "/*";.

6 голосов
/ 18 мая 2009

FAQ:

perldoc -q comment

Найдено в perlfaq6 :

Как использовать регулярное выражение для удаления комментариев в стиле C из файла?

Хотя это на самом деле можно сделать, это гораздо сложнее, чем вы думаете. За например, этот однострочный ...

1 голос
/ 18 августа 2009

Существует также не-Perl ответ: используйте программу Газа :

StripCmt - простая утилита, написанная в C удалить комментарии из C, C ++, и исходные файлы Java. В большом традиция обработки текста Unix программы, он может функционировать как Фильтр FIFO (First In - First Out) или принимать аргументы в командной строке.

0 голосов
/ 18 мая 2009

Удалить / * * / комментарии (в том числе многострочные)

s/\/\*.*?\*\///gs

Я публикую это, потому что это просто, но я полагаю, что это приведет к сбою во встроенных комментариях типа

/* sdafsdfsdf /*sda asd*/ asdsdf */

Но поскольку они довольно необычны, я предпочитаю простое регулярное выражение.

0 голосов
/ 18 мая 2009

Включая тесты:

use strict;
use warnings;
use Test::More qw(no_plan);
sub strip_comments {
  my $string=shift;
  $string =~ s#/\*.*?\*/##sg; #strip multiline C comments
  return $string;
}
is(strip_comments('a/* comment1 */  code   /* comment2 */b'),'a  code   b');
is(strip_comments('a/* comment1 /* comment2 */b'),'ab');
is(strip_comments("a/* comment1\n\ncomment */ code /* comment2 */b"),'a code b');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...