Как я могу переместить комментарии C от начала строки до конца, используя Perl? - PullRequest
1 голос
/ 19 мая 2009

Как я могу проверить следующую строку во время работы в токовой петле? Кроме того, как я могу переместить комментарии C в конец строки для таблицы?

У меня есть такой файл:

array_table=
{
    /* comment 1*/ (unsigned int a); 
    /* comment 2*/ (unsigned int b); 
    /* comment 3*/ (unsigned int c); 
    /* comment 4*/ (unsigned int d);
}

Я собираюсь переместить эти комментарии в конец строки, например:

array_table=
{
    (unsigned int a); /* comment 1*/
    (unsigned int b); /* comment 2*/
    (unsigned int c); /* comment 3*/ 
    (unsigned int d); /* comment 4*/
}

Как я могу сделать это в Perl? Кто-нибудь может мне помочь с кодом Perl?

Ответы [ 4 ]

1 голос
/ 19 мая 2009

ОК - чтобы переформулировать то, что, как я думаю, вы запрашиваете, вы хотите проанализировать файл и найти присвоения формы

foo=
   {
       ....
   }

и внутри блока вы хотите переместить комментарии в конец строки. Есть несколько способов сделать это, самый элегантный обычно связан с тем, что еще вы делаете в цикле. Единственное, что приходит на ум, - это просто вспомнить тот факт, что в последней строке содержался символ «=», и использовать этот факт при сопоставлении с «{» в начале строки. Используя одну из моих любимых конструкций perl, оператор диапазона в скалярном контексте. Так что это дало бы ...

my $last_line_an_assignment = 0;
while (<DATA>)
{
    if (($last_line_an_assignment && m!^\s*{!) .. m!^\s*}!)
    {
        s!(/\*.*?\*/)\s*(.*)$!$2 $1!;
    }

    print $_;

    $last_line_an_assignment = m!=!;
}

__DATA__

  /* comment other */ (unsigned int a); 

  other_assignment=
     /* not a table */ 12;

  array_table=
      {
        /* comment 1*/ (unsigned int a); 
        /* comment 2*/ (unsigned int b); 
        /* comment 3*/ (unsigned int c); 
        /* comment 4*/ (unsigned int d);
      }

  /* comment other */ (unsigned int a); 

Вы можете либо распечатать данные в другой файл, либо обновить файлы на месте, используя параметр '-i' для perl

local (@ARGV) = ($filename);
local ($^I) = '.bak';
while (<>)
{
    # make changes to line AND call print
}

Это заставляет perl сделать резервную копию $ filename (с расширением '.bak'), и тогда все вызовы печати в цикле перезапишут содержимое, если файл - для получения дополнительной информации см. Опцию '-i' в Страница руководства "perlrun".

1 голос
/ 19 мая 2009

Примерно так должно работать:

while (<>) {
    chomp;
    if ($_ =~ m%^(.*)/\*(.*)\*/(.*)$%) {
            printf "%s%s/*%s*/%s", $1, $3, $2, $/;
    } else {
            print $_ . $/;
    }
}

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

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

Используйте Regexp :: Common вместо собственного. Э.Г.

use Regexp::Common;

while ($_ = <DATA>) {
    chomp;
    if (s/(^\s*)($RE{comment}{C})//) {
        print $1, $_, $2, "\n";
    }
    else {
        print $_, "\n";
    }
}

__DATA__
              /* comment other */ (unsigned int a); 

              other_assignment=
                 /* not a table */ 12;

              array_table=
                  {
                    /* comment 1*/ (unsigned int a); 
                    /* comment 2*/ (unsigned int b); 
                    /* comment 3*/ (unsigned int c); 
                    /* comment 4*/ (unsigned int d);
                  }

              /* comment other */ (unsigned int a);
0 голосов
/ 19 мая 2009

Если вы хотите изменить только комментарии внутри array_table оператора:

perl -pe's,^(\s*)(/\*.*?\*/)\s*(.*?)[ \t]*$,$1$3 $2, if/^\s*array_table\s*=/../^\s*\}/'

иначе просто:

perl -pe's,^(\s*)(/\*.*?\*/)\s*(.*?)[ \t]*$,$1$3 $2,'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...