3

输入文件:

{test test
{***********************************************************************
{Rtest
{***********************************************************************
{test
{***********************************************************************
{* date
{*
{* Initial revision
{*
{***********************************************************************

{output}

{output1}

{output 2}

{Test TEst TEST}  
{Test test test}

{*********************}

{********************}

所需输出:

{Output}
{output1}
{output2}

脚本

use strict;
use warnings;

while (<DATA>) {
  $line = $_;
  chomp $line;

  push( @lines, $line );

  $line =~ s/^\s+//;
  $line =~ s/\s+$//;

  for ( my $i = 0 ; $i <= $#lines ; $i++ ) {
    if ( $lines[$i] =~ m/(^{\**$)/ ) {

      push( @matched, $lines[ $i + 1 ] );
      print "$lines[$i+1]"."\n";
    }
  }
}

我的输出:

 {test test
    {***********************************************************************
    {Rtest
    {***********************************************************************
    {test
    {***********************************************************************
    {* date
    {*
    {* Initial revision
    {*
    {***********************************************************************

我能够匹配顶部块,但无法获得所需的前 3 行作为输出。从上面的匹配条件中,我试图提取下一行,但我得到一个空格作为输出。我错过了什么吗,在此先感谢。

4

3 回答 3

3

这个程序是我对你可能想要的最好的猜测。它需要命令行上的输入文件。

我已经编写了它,以便它在以 . 开头的行之后打印接下来的三个非空白行{*。但我无法理解什么规则会排除这些行

{Rtest

{test

但包括你说你想要的那些。如果您还需要什么,请再次询问。

更新

也许您只想打印那些}? 我已经改变了我的代码来做到这一点

use strict;
use warnings;

my @lines;
my @matched;

my $n = 0;

while (<>) {
  if ( /^\s*\{\*+/ ) {
    $n = 3;
  }
  elsif ( $n and /\}\s*$/ ) {
    print;
    $n-- ;
  }
}

输出

{output}
{output1}
{output 2}
于 2012-07-17T11:00:55.157 回答
3

更新:最后一次编辑后,此答案不再有效,因为 OP 已更改所需的输出。

这可以非常简单地完成。只需删除所有以卷曲开头的行{和空行。

use strict; use warnings;
use Data::Dumper;
my @output;
while (<DATA>) {
  chomp;           # remove newline
  next if /^\{\*/; # We don't want lines starting with an open curly and an asterisk
  next if /^\s*$/; # We also do not want lines that are empty
  push @output, $_;
}

print Dumper \@output;

输出:

$VAR1 = [
          'output',
          'output1',
          'output 2'
        ];
于 2012-07-17T07:29:53.017 回答
0

我不知道您为什么要通过积压的行返回并反复将它们推入-尤其是当它们与您说要获得的输出@matched匹配时。这样比较好...

while ( <DATA> ) { 
    print if m/^[{]o/i;
}

但它并没有达到你指定的输出,因为没有对应的输入行'{Output}'or'{output2}'只有'{output}'and '{output 2}',所以,以防万一它不仅仅是草率的规范,我们可能不得不修改它。

while ( <DATA> ) { 
    next unless my ( $n ) = m/^[{]output\s*(\d)?[}]/i;
    my $output = length $n ? 'output' : 'Output';
    say "{$output$n}";
}
于 2012-07-17T12:45:59.547 回答