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'
];