Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 正则表达式匹配不会在perl中生成输出_Regex_Perl - Fatal编程技术网

Regex 正则表达式匹配不会在perl中生成输出

Regex 正则表达式匹配不会在perl中生成输出,regex,perl,Regex,Perl,我有一个如下的测试文件: t # 3-0, 1 v 0 0 v 1 19 v 2 2 u 0 1 2 u 0 2 2 u 1 2 2 t # 3-1, 1 v 0 0 v 1 15 v 2 2 u 0 1 2 u 0 2 2 u 1 2 2 t # 3-2, 1 v 0 0 v 1 17 v 2 2 u 0 1 2 u 0 2 2 u 1 2 2 t # 3-3, 1 v 0 0 v 1 18 v 2 7 u 0 1 2 u 0 2 2 u 1 2 2 我编写了以下代码以匹配事务的最后三行(每

我有一个如下的测试文件:

t # 3-0, 1
v 0 0
v 1 19
v 2 2
u 0 1 2
u 0 2 2
u 1 2 2
t # 3-1, 1
v 0 0
v 1 15
v 2 2
u 0 1 2
u 0 2 2
u 1 2 2
t # 3-2, 1
v 0 0
v 1 17
v 2 2
u 0 1 2
u 0 2 2
u 1 2 2
t # 3-3, 1
v 0 0
v 1 18
v 2 7
u 0 1 2
u 0 2 2
u 1 2 2
我编写了以下代码以匹配事务的最后三行(每个事务以
t#
开头)


请您尝试以下方法:

#!/usr/bin/perl -w

my $ref;
open(FH, shift) or die;
while (<FH>) {
    chop;
    if (/^t\s*#/) {            # if a new transaction starts
        $ref = [];             # then create a new reference to an array
        push(@refs, $ref);     # and memorize the reference
    }
    push(@$ref, $_);           # append the line to the current array
}
for $ref (@refs) {
    print(join(" " x 4, $ref->[0], $ref->[-3], $ref->[-2], $ref->[-1]), "\n");
}

一种方法:将事务的所有行保存在缓冲区中,当您到达一个新的事务id时,将前一行以及该缓冲区中的最后三行一起存储

use warnings;
use strict;
use feature 'say';

my (@transactions, @trans_lines, $tid);

while (<>) { 
    chomp;

    if (/^(t\s*#\s*[0-9,\s-]+)/) { 
        if (not $tid) {      
            $tid = $1;   # the very first one starts
            next;
        }

        # Store previous id and its last three lines, reset
        push @transactions, [ $tid, @trans_lines[-3..-1] ];
        $tid = $1; 
        @trans_lines = ()
    }   

    push @trans_lines, $_; 
}


say "@$_" for @transactions;
或者,更好的方法是使用更完整的用法消息调用例程,等等


  • 使用词法文件句柄,
    打开我的$fh,您的代码按原样为我提供以下输出:

    t # 3-0, 1  u 0 1 2 u 0 2 2 u 1 2 2
    t # 3-1, 1  u 0 1 2 u 0 2 2 u 1 2 2
    t # 3-2, 1  u 0 1 2 u 0 2 2 u 1 2 2
    t # 3-3, 1  u 0 1 2 u 0 2 2 u 1 2 2
    
    看来问题出在你没给我们看的东西上。可能输入文件来自不同的系统,并且具有系统无法识别的行尾

    嵌套的
    while
    循环和
    if
    条件使代码比需要的更复杂(因此更难维护)。您可以使用以下方法在一个循环中完成所有操作:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my $input = shift @ARGV or die $!;
    
    open (my $fh, '<', $input) or die $!;
    
    my ($transaction_id, $edge_1, $edge_2, $edge_3);
    
    while (<$fh>) {
      if (m/^(t\h*#\h*[0-9,\h-]+)/) {
        $transaction_id = $1;
      } elsif (m/^(u\h+[0]\h+[1]\h+[2])/) {
        $edge_1 = $1;
      } elsif (m/^(u\h+[0]\h+[2]\h+[2])/) {
        $edge_2 = $1;
      } elsif (m/^(u\h+[1]\h+[2]\h+[2])/) {
        $edge_3 = $1;
      }
    
      if ($transaction_id and $edge_1 and $edge_2 and $edge_3) {
        print "$transaction_id\t$edge_1\t$edge_2\t$edge_3\n";
        ($transaction_id, $edge_1, $edge_2, $edge_3) = (undef) x 4;
      }
    }
    
    #/usr/bin/perl
    严格使用;
    使用警告;
    my$input=shift@ARGV或die$!;
    
    打开(my$fh),定义正则表达式模式
    $skip
    $data
    $tran
    ,遍历数据,组装事务行并在新事务开始时推入数组

    use strict;
    use warnings;
    use feature 'say';
    
    use Data::Dumper;
    
    my $skip = qr/^v \d+ \d+/;
    my $data = qr/^u \d+ \d+ \d+/;
    my $tran = qr/^t # \d-\d, \d/;
    
    my @array;
    my $line = <DATA>;
    
    chomp($line);
    
     while( <DATA> ) {
        next if /$skip/;
        chomp;
        $line .= '  ' . $_ if /$data/;
        if( /$tran/ ) {
            push @array, $line;
            $line = $_;
        }
    }
    
    push @array, $line;
    
    say Dumper(\@array);
    
    __DATA__
    t # 3-0, 1
    v 0 0
    v 1 19
    v 2 2
    u 0 1 2
    u 0 2 2
    u 1 2 2
    t # 3-1, 1
    v 0 0
    v 1 15
    v 2 2
    u 0 1 2
    u 0 2 2
    u 1 2 2
    t # 3-2, 1
    v 0 0
    v 1 17
    v 2 2
    u 0 1 2
    u 0 2 2
    u 1 2 2
    t # 3-3, 1
    v 0 0
    v 1 18
    v 2 7
    u 0 1 2
    u 0 2 2
    u 1 2 2
    
    my $file = shift @ARGV  // die "Usage: $0 file\n";
    
    t # 3-0, 1  u 0 1 2 u 0 2 2 u 1 2 2
    t # 3-1, 1  u 0 1 2 u 0 2 2 u 1 2 2
    t # 3-2, 1  u 0 1 2 u 0 2 2 u 1 2 2
    t # 3-3, 1  u 0 1 2 u 0 2 2 u 1 2 2
    
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my $input = shift @ARGV or die $!;
    
    open (my $fh, '<', $input) or die $!;
    
    my ($transaction_id, $edge_1, $edge_2, $edge_3);
    
    while (<$fh>) {
      if (m/^(t\h*#\h*[0-9,\h-]+)/) {
        $transaction_id = $1;
      } elsif (m/^(u\h+[0]\h+[1]\h+[2])/) {
        $edge_1 = $1;
      } elsif (m/^(u\h+[0]\h+[2]\h+[2])/) {
        $edge_2 = $1;
      } elsif (m/^(u\h+[1]\h+[2]\h+[2])/) {
        $edge_3 = $1;
      }
    
      if ($transaction_id and $edge_1 and $edge_2 and $edge_3) {
        print "$transaction_id\t$edge_1\t$edge_2\t$edge_3\n";
        ($transaction_id, $edge_1, $edge_2, $edge_3) = (undef) x 4;
      }
    }
    
    use strict;
    use warnings;
    use feature 'say';
    
    use Data::Dumper;
    
    my $skip = qr/^v \d+ \d+/;
    my $data = qr/^u \d+ \d+ \d+/;
    my $tran = qr/^t # \d-\d, \d/;
    
    my @array;
    my $line = <DATA>;
    
    chomp($line);
    
     while( <DATA> ) {
        next if /$skip/;
        chomp;
        $line .= '  ' . $_ if /$data/;
        if( /$tran/ ) {
            push @array, $line;
            $line = $_;
        }
    }
    
    push @array, $line;
    
    say Dumper(\@array);
    
    __DATA__
    t # 3-0, 1
    v 0 0
    v 1 19
    v 2 2
    u 0 1 2
    u 0 2 2
    u 1 2 2
    t # 3-1, 1
    v 0 0
    v 1 15
    v 2 2
    u 0 1 2
    u 0 2 2
    u 1 2 2
    t # 3-2, 1
    v 0 0
    v 1 17
    v 2 2
    u 0 1 2
    u 0 2 2
    u 1 2 2
    t # 3-3, 1
    v 0 0
    v 1 18
    v 2 7
    u 0 1 2
    u 0 2 2
    u 1 2 2
    
    $VAR1 = [
              't # 3-0, 1  u 0 1 2  u 0 2 2  u 1 2 2',
              't # 3-1, 1  u 0 1 2  u 0 2 2  u 1 2 2',
              't # 3-2, 1  u 0 1 2  u 0 2 2  u 1 2 2',
              't # 3-3, 1  u 0 1 2  u 0 2 2  u 1 2 2'
            ];