我正在尝试在数组中找到两个模式,并将结果放入另一个数组中。
例如
$/ = "__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
答案 0 :(得分:1)
该代码不仅仅打印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>
答案 1 :(得分:0)
#! /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 # put this line into @arrayNewLines - ccccccccccccccc # put this line into @arrayNewLines