我试图在一个数组中找到两个模式并将结果放入另一个数组中。
例如
$/ = "__Data__";
__Data__
#SCSI_test # put this line into @arrayNewLines
kdkdkdkdkdkdkdkd
dkdkdkdkdkdkdkdkd
- ccccccccccccccc # put this line into @arrayNewLines
代码
while(<FILEREAD>)
{
chomp;
my @arrayOld = split(\n,@array);
foreach my $i (0 .. $#arrayOld)
{
if($arrayOld[$i] =~ /^-(.*)/g or /\#(.*)/g)
{
my @arrayNewLines = $arrayOld[$i];
print "@arrayNewLines\n";
}
}
}
此代码仅打印出 ccccccccccccccc 但我希望它输出 ccccccccccccccc #SCSI_test
该代码不仅仅打印
cccccc...
,它还打印所有内容。你的问题是这一行:
if($arrayOld[$i] =~ /^-(.*)/g or /\#(.*)/g) {
您在这里所做的是首先检查
$arrayOld[$i]
,然后检查 $_
,因为 /\#(.*)/
是 $_ =~ /\#(.*)/
的 Perl 简写。由于该行包含哈希字符 #
,因此它将始终匹配,并且该行将始终打印。
您的行相当于:
if( $arrayOld[$i] =~ /^-(.*)/g
or
$_ =~ /\#(.*)/g) {
答案是加入正则表达式:
if($arrayOld[$i] =~ /^-|#/) {
但是,在那之后你的代码远非干净......从顶部开始:
如果使用该输入将输入记录分隔符
$/
设置为 __Data__
,您将获得两条记录(Data::Dumper 输出如下所示):
$VAR1 = '__Data__';
$VAR1 = '
#SCSI_test # put this line into @arrayNewLines
kdkdkdkdkdkdkdkd
dkdkdkdkdkdkdkdkd
- ccccccccccccccc # put this line into @arrayNewLines
';
当您
chomp
记录时,您将从末尾删除__Data__
,因此第一行将变为空。所以本质上,你将永远有一个领先的空字段。这并不可怕,但值得记住。
您的
split
陈述是错误的。首先,第一个参数应该是正则表达式:/\n/
。第二个参数应该是标量,而不是数组。 split(/\n/,@array)
将计算为 split(/\n/, 2)
,因为数组位于标量上下文中并返回其大小而不是其元素。
当然,由于您处于循环中从
FILEREAD
句柄读取行,因此 @array
数组将始终包含相同的数据,并且与文件句柄中的数据无关。你想要的是:split /\n/, $_
.
这个循环:
foreach my $i (0 .. $#arrayOld) {
对于这个问题来说并不是一个很好的循环结构。此外,无需使用中间数组。只需使用:
for my $line (split /\n/, $_) {
当你这样做时
my @arrayNewLines = $arrayOld[$i];
print "@arrayNewLines\n";
您将整个数组设置为标量,然后打印它,这是完全多余的。只需直接打印标量即可获得相同的效果。
您的代码应如下所示:
while(<FILEREAD>) {
chomp;
foreach my $line (split /\n/, $_) {
if($line =~ /^-|#/) {
print "$line\n";
}
}
}
还建议您使用词法文件句柄,因此不要使用
open FILEREAD, "somefile" or die $!; # read with <FILEREAD>
用途:
open my $fh, "<", "somefile" or die $!; # read with <$fh>
#! /usr/bin/env perl
use strict;
use warnings;
*ARGV = *DATA;
my @arrayNewLines;
while (<>) {
chomp;
if (/^-(.*)/ || /\#(.*)/) {
push @arrayNewLines, $_;
}
}
print "$_\n" for @arrayNewLines;
__DATA__
#SCSI_test # put this line into @arrayNewLines
kdkdkdkdkdkdkdkd
dkdkdkdkdkdkdkdkd
- ccccccccccccccc # put this line into @arrayNewLines
更好的是,如果您有 5.10 或更高版本,请使用智能匹配。
#! /usr/bin/env perl
use strict;
use warnings;
use 5.10.0; # for smart matching
*ARGV = *DATA;
my @arrayNewLines;
my @patterns = (qr/^-(.*)/, qr/\#(.*)/);
while (<>) {
chomp;
push @arrayNewLines, $_ if $_ ~~ @patterns;
}
print "$_\n" for @arrayNewLines;
__DATA__
#SCSI_test # put this line into @arrayNewLines
kdkdkdkdkdkdkdkd
dkdkdkdkdkdkdkdkd
- ccccccccccccccc # put this line into @arrayNewLines
无论哪种方式,输出都是
#SCSI_test # 将此行放入@arrayNewLines - ccccccccccccccc #将此行放入@arrayNewLines