Perl включает строки продолжения и игнорирует двойные кавычки

Я работал над сценарием, который должен создавать foo для первых двух строк и bar для последних трех. Здесь я столкнулся с двумя проблемами.

  1. Как заставить Perl игнорировать двойные кавычки вокруг первого foo?

  2. Как мне заставить его распознать обратную косую черту как линию продолжения? -

Пример ввода:

reset -name "foo"
quasi_static -name foo
reset \
-name bar
set_case_analysis -name "bar"

Мой код:

   if (/^\s*set_case_analysis.*\-name\s+(\S+)/) 
   {
      $set_case_analysis{$1}=1;
      print "Set Case $1\n";
   } 
   elsif (/^\s*quasi_static.*\-name\s+(\S+)/) 
   {
      $quasi_static{$1}=1;
      print "Quasi Static $1\n";
   } 
   elsif (/^\s*reset\s+.*\-name\s+(\S+)/) 
   {
      $reset{$1}=1;
      print "Reset $1\n";
    }

person synarchy007    schedule 07.08.2018    source источник
comment
Вы читаете эти данные построчно из файла? Всегда ли символ продолжения строки находится на одном и том же месте?   -  person i alarmed alien    schedule 07.08.2018
comment
Да, данные читаются построчно. Символ продолжения строки не всегда появляется в одном и том же столбце текста, но когда он появляется, он находится на последнем месте строки. @ialarmedalien   -  person synarchy007    schedule 07.08.2018


Ответы (1)


Если вы просматриваете файл построчно, вы можете сохранить частичные строки в переменной и объединить их со следующей строкой. Прочтите код - я прокомментировал функциональность.

my $curr;
my $txt;
open ( IN, "<", 'yourinputfile.txt' ) or die 'Could not open file: ' . $!;
while (<IN>) {
  chomp;
  # if the line ends with a backslash, save the segment in $curr and go on to the next line
  if ( m!(.*?) \$! ) {
    $curr = $1;
    next;
  }
  # if $curr exists, add this line on to it
  if ( $curr ) {
    $curr .= $_;
  }
  # otherwise, set $curr to the line contents
  else {
    $curr = $_;
  }

  if ( $curr =~ /set_case_analysis -name\s+\"?(\S+)/) {
      # if the string is in quotes, the regex will leave the final " on the string
      # remove it
      ( $txt = $1 ) =~ s/"$//;
      print "Set Case $txt\n";
      $set_case_analysis{$txt}=1;
   }
   elsif ($curr =~ /quasi_static -name\s+(\S+)/) {
      ( $txt = $1 ) =~ s/"$//;
      print "Quasi Static $txt\n";
      $quasi_static{$txt}=1;

   }
   elsif ($curr =~ /reset .*?-name\s+\"?(\S+)/) {
      ( $txt = $1 ) =~ s/"$//;
      print "Reset $txt\n";
      $reset{$txt}=1;
  }
  # reset $curr
  $curr = '';
}

Вы можете сделать его более компактным и аккуратным, сделав что-то вроде этого:

if ( $curr =~ /(\w+) -name \"?(\S+)/) {
      ( $txt = $2 ) =~ s/"$//;
      $data{$1}{$txt}=1;
}

Вы получите вложенную хеш-структуру с тремя ключами set_case_analysis, quasi_static и reset и различными значениями из -name.

%data = (
  quasi_static => ( foo => 1, bar => 1 ),
  reset => ( pip => 1, pap => 1, pop => 1 ),
  set_case_analysis => ( foo => 1, bar => 1 )
);
person i alarmed alien    schedule 07.08.2018
comment
Я новичок в Perl, поэтому немного запутался в регулярных выражениях, но могу следить за ними. Я продолжаю получать ошибки, в которых говорится: «Требуется конкретное имя пакета». Есть ли какие-то пакеты, которые мне нужно импортировать? - person synarchy007; 09.08.2018
comment
все вышеперечисленное - это ванильный Perl, который должен работать без каких-либо специальных настроек. Есть ли еще код, который может вызывать ошибку? Можете ли вы опубликовать полное сообщение об ошибке? - person i alarmed alien; 09.08.2018
comment
В настоящее время я получаю синтаксические ошибки в скобках моего первого раздела кода, опубликованного выше. Должен ли я удалить его, поскольку все, что он делает, - это помещает значения в переменные? Разве это не то, что делают ваши правки? - person synarchy007; 10.08.2018