如何使用perl正则表达式在数组中循环查找多个模式?
我试图在一个数组中找到两个模式,并将结果放入另一个数组中 比如说如何使用perl正则表达式在数组中循环查找多个模式?,perl,Perl,我试图在一个数组中找到两个模式,并将结果放入另一个数组中 比如说 $/ = "__Data__"; __Data__ #SCSI_test # put this line into @arrayNewLines kdkdkdkdkdkdkdkd dkdkdkdkdkdkdkdkd - ccccccccccccccc # put this line into @arrayNewLines 代码 while() { 咀嚼; my@array
$/ = "__Data__";
__Data__
#SCSI_test # put this line into @arrayNewLines
kdkdkdkdkdkdkdkd
dkdkdkdkdkdkdkdkd
- ccccccccccccccc # put this line into @arrayNewLines
代码
while()
{
咀嚼;
my@arrayOld=split(\n,@array);
每个我的$i(0..$#arrayOld)
{
如果($arrayOld[$i]=~/^-(.*)/g或/\\\\(.*)/g)
{
my@arrayNewLines=$arrayOld[$i];
打印“@arrayNewLines\n”;
}
}
}
此代码仅打印CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
但我希望它能输出CCCCCCC#SCSI(u test#/usr/bin/env perl
严格使用;
使用警告;
*ARGV=*数据;
我的@arrayNewLines;
而(){
咀嚼;
如果(/^-(.*)/|/|/\#(.*)/){
推送@arrayNewLines,$\;
}
}
为@arrayNewLines打印“$\un”;
__资料__
#SCSI#U测试#将此行放入@arrayNewLines
KdKdKdKdKdKd
DKDKDKDKDKD
-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
更好的是,如果你有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
#/usr/bin/env perl
严格使用;
使用警告;
使用5.10.0;#智能匹配
*ARGV=*数据;
我的@arrayNewLines;
我的@patterns=(qr/^-(.*)/,qr/\\\\\\\\\\\(.*)/;
而(){
咀嚼;
按@arrayNewLines,$\uIf$\uIf~~@patterns;
}
为@arrayNewLines打印“$\un”;
__资料__
#SCSI#U测试#将此行放入@arrayNewLines
KdKdKdKdKdKd
DKDKDKDKDKD
-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
无论哪种方式,输出都是
#SCSI_test # put this line into @arrayNewLines
- ccccccccccccccc # put this line into @arrayNewLines
#SCSI#U测试#将此行放入@arrayNewLines
-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC。您的问题是这一行:
if($arrayOld[$i] =~ /^-(.*)/g or /\#(.*)/g) {
这里要做的是首先检查$arrayOld[$i]
,然后检查$\u
,因为/\\35;(.*)/
是$\u=~/\\ 35;(.*)/
的perl缩写。由于该行包含哈希字符#
,因此它将始终匹配,并且该行将始终打印
您的线路相当于:
if( $arrayOld[$i] =~ /^-(.*)/g
or
$_ =~ /\#(.*)/g) {
答案是加入正则表达式:
if($arrayOld[$i] =~ /^-|#/) {
然而,在那之后,您的代码还远远不够干净。。。从顶部开始:
如果使用该输入将输入记录分隔符$/
设置为\uuuu Data\uuuu
,则将获得两条记录(输出如下所示):
当您chomp
记录时,您将从末尾删除\uuuuu Data\uuuu
,因此第一行将变为空。所以在本质上,你总是有一个前导的空字段。这没什么可怕的,但要记住
您的split
语句是错误的。首先,第一个参数应该是正则表达式:/\n/
。第二个参数应该是标量,而不是数组split(/\n/,@array)
将计算为split(/\n/,2)
,因为数组位于标量上下文中,返回其大小而不是元素
当然,由于您在循环中从FILEREAD
句柄读取行,因此@array
数组将始终包含相同的数据,而与文件句柄中的数据无关。您需要的是:split/\n/,$\u
此循环:
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";
}
}
}
while(){
咀嚼;
foreach my$行(拆分/\n/,$){
如果($line=~/^-|#/){
打印“$line\n”;
}
}
}
还建议您使用词法文件句柄,因此
open FILEREAD, "somefile" or die $!; # read with <FILEREAD>
openfileread,“somefile”或die$!#阅读
使用:
打开我的$fh,/^-(.*)/|/\(.*)/
最好写为/^-|/
。不确定为什么选择只为-
匹配行首,但如果是打字错误,则更有效地编写:/^[-]/
。如果不使用括号,则使用括号是没有意义的;如果不使用括号,则匹配括号也是没有意义的。
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>