Соответствие слову, но не в комментарии

Я пытаюсь сопоставить слово, но не в тех случаях, когда ему предшествует комментарий (/*, за которым не следует */). Я пытался использовать отрицательные прогнозные утверждения, чтобы сделать это, но пока безуспешно. Будет ли это возможно с утверждениями отрицательного взгляда вперед или отрицательного взгляда назад, или это тщетные усилия?


person umop    schedule 30.06.2012    source источник
comment
Где ваши усилия? Можете ли вы включить то, что вы пробовали.   -  person Tim Cooper    schedule 30.06.2012


Ответы (1)


Я просто предполагаю, что вы пишете сценарий Perl, пытаясь проанализировать код C.

Это может быть какое-то единственное элегантное регулярное выражение, но тогда вам нужно прочитать весь файл и сделать его одной строкой. Я помню, что у меня были проблемы, когда я пытался запустить регулярное выражение Perl для строк, содержащих несколько строк (\n символов), но, возможно, это только я.

В любом случае, я бы предложил вам обработать его построчно, позаботившись о 3 случаях:

  1. Однострочный комментарий: /* my comment */
  2. Комментарий, начинающийся с текущей строки: /* my comment starts here
  3. Комментарий, заканчивающийся на текущей строке: my comment ends here */

Удалите комментарий из анализируемого текста, а в остальном ищите свое слово. Что-то вроде этого:

#!/usr/bin/perl
use strict;
use warnings;

my $word = shift;
my $line_no = 0;
my $whole_line = "";

my $in_comment = 0;

sub word_detection
{
    while ($_ =~ /\b($word)\b/g)
    {
        print "'$1' found on line $line_no: $whole_line\n";
    }
}

while (<>)
{
    chomp;
    $whole_line = $_;
    $line_no ++;

    $_ =~ s/\/\*.*?\*\///;

    if ($_ =~ /\/\*/)
    {
        my @split = (split /\/\*/,  $_);
        $_ = $split[0];
        $in_comment = 1;
        word_detection $_;
    }
    elsif ($_ =~ /\*\//)
    {
        my @split = (split /\*\//,  $_);
        $_ = $split[1];
        $in_comment = 0;
        word_detection $_;
    }
    elsif (not $in_comment)
    {
        word_detection $_;
    }
}

Запустите этот скрипт с вашим словом в качестве первого аргумента («int» в приведенном ниже примере), а затем с вашим именем файла. Он должен выполнять работу:

$ match-word int test.cc
'int' found on line 11: int /* comment on one line */ x = 10;
'int' found on line 13: int y; /* and this is
'int' found on line 15:     comment */ int z;
'int' found on line 17: int main(int argc, char* argv[])
'int' found on line 17: int main(int argc, char* argv[])
person Peter Al    schedule 30.06.2012
comment
/* и */ также могут встречаться внутри строкового литерала или однострочного комментария. - person Bart Kiers; 30.06.2012