有一个存储在数组中的标签(字符串)列表。还有另一个数组,包含一些正则表达式(作为字符串)。需要通过这些正则表达式过滤标记。
以下代码是问题的演示。
#!/usr/bin/env perl
use 5.014;
use warnings;
my @re = @ARGV;
say "filters: @re";
my $line;
while(<DATA>) {
chomp;
$line = $_;
my $res = checktags(@re) ? "OK" : "NO";
say "$res for $line";
}
sub checktags {
my(@filters) = @_;
for my $tag (split /\s+/, $line) { #check each tag
for my $r (@filters) { #with each filter
#say "checking tag: $tag for regex: $r";
return undef unless( $tag =~ $r ); # <--- HOW HERE???
say "\tpassed";
}
}
return 1;
}
__DATA__
aaaxxx bbb
aaa xxx bbb
aaa ccc
bbb ddd
aaa zzzbbb
E.g。用于调用脚本
perl so2.pl '/(aaa|bbb)/' '!/(xxx|zzz)/'
所以:其中一个代码必须与aaa
或bbb
和匹配,没有一个代码可以匹配xxx
或zzz
,因此应该打印:
filters: /(aaa|bbb)/ !/(xxx|zzz)/
NO for aaaxxx bbb #no, because one of tags matches /xxx/
NO for aaa xxx bbb #no, as above
OK for aaa ccc #ok, matches /aaa/ and here isn't /(xxx|zzz)/
OK for bbb ddd #ok, as above for /bbb/
NO for #no, no /aaa/ nor /bbb/
NO for aaa zzzbbb #no, here is /zzz/
答案 0 :(得分:0)
经过两次不同的错误逻辑尝试后,解决了以下问题:
sub checktags {
my(@filters) = @_;
my @tags = split /\s+/, $line;
for my $r (@filters) {
if( my($negate,$restr) = ( $r =~ m{^\s*(!)?/(.*)/\s*$}) ) {
my $res = any { $_ =~ qr/$restr/ } @tags;
return if( ($negate && $res) || (!$negate && !$res));
}
else {
warn "Wrong filter $r - skipping";
}
}
return @tags;
}
打印想要的内容:
filters: /(aaa|bbb)/ !/(xxx|zzz)/
NO for aaaxxx bbb
NO for aaa xxx bbb
OK for aaa ccc
OK for bbb ddd
NO for
NO for aaa zzzbbb