我有一个字符串,其中包含以空格分隔的标记列表。
my $string = "--configure-option1 --configure-option2 --configure-option3 --configure-option4";
我有一组类似的字符串。
my @array = (
"--configure-option20",
"--configure-option2 --configure-option5",
"--configure-option10 --configure-option11",
"--configure-option15 --configure-option22 --configure-option27",
);
我想确定$string
中的一个字符串中是否也找到了@array
中的任何标记。例如,对于上述值,结果都是正确的,因为两者都是$string
和$array[1]
包含令牌--configure-option2
。
答案 0 :(得分:4)
my $alt = join '|', map quotemeta, split ' ', $string;
my $re = qr/(?<!\S)(?:$alt)(?!\S)/;
my $match = grep /$re/, @array;
为了加速一些事情:
my $match = join(' ', @array) =~ /$re/;
为了加快速度,节省内存:
my $match = 0
for (@array) {
if (/$re/) {
$match = 1;
last;
}
}
答案 1 :(得分:2)
如果我猜错了你的数据格式,我认为这可以解决你的问题
它将@failures
数组转换为包含所有不同选项的哈希值,这些选项如果出现则会导致拒绝。然后它通过@array
(你的名字,而不是我的!)并使用grep
来检查%failures
哈希中是否出现任何组成选项,并打印结果
如果速度有问题,那么您可能希望将grep
替换为any
来自List::MoreUtils
use strict;
use warnings;
use 5.010;
my @array = (
'--configure-option1 --configure-option2 --configure-option3 --configure-option4',
'--configure-option3 --configure-option4 --configure-option12',
);
my @failures = (
'--configure-option20',
'--configure-option2 --configure-option5',
'--configure-option10 --configure-option11',
'--configure-option15 --configure-option22 --configure-option27',
);
my %failures;
$failures{$_} = 1 for map split, @failures;
for my $options ( @array ) {
my $reject = grep { $failures{$_} } split ' ', $options;
say $options, ' ', $reject ? 'FAIL' : 'PASS';
}
--configure-option1 --configure-option2 --configure-option3 --configure-option4 FAIL
--configure-option3 --configure-option4 --configure-option12 PASS
答案 2 :(得分:1)
你的问题还很不清楚。根据我能读到的内容,我想出了这个:
#!/usr/bin/env perl
use strict;
use warnings;
use Set::CrossProduct;
my $x = '[--configure-option1 --configure-option2 --configure-option3 --configure-option4]';
my $y = '[--configure-option20][--configure-option2 --configure-option5][--configure-option10 --configure-option11][--configure-option15 --configure-option22 --configure-option27]';
my $pat = qr/([a-z0-9-]+)/;
my @x = ($x =~ /$pat/g);
my @y = ($y =~ /$pat/g);
my $it = Set::CrossProduct->new([\@x, \@y]);
while (my $el = $it->get) {
if ($el->[0] eq $el->[1]) {
printf "'%s' appears in both\n", $el->[0];
}
}
输出:
C:\...\Temp> perl tt.pl '--configure-option2' appears in both
答案 3 :(得分:-2)
#!/usr/bin/perl
my @pairs = (
'--configure-option1 --configure-option2 --configure-option3 --configure-option4',
'--configure-option3 --configure-option4 --configure-option12',
);
my @failures = (
'--configure-option20',
'--configure-option2 --configure-option5',
'--configure-option10 --configure-option11',
'--configure-option15 --configure-option22 --configure-option27',
);
$all = 0;
$size = $#pairs + 1;
my $string1;
my $string2;
while ($all < $size) {
##... Other code happening here
## Begin test case
####################################################
# loop through the existing failure cases. Logic here is that
# the failures array will always be < the build array.
# (the full build array has thousands of options while the
# failures array can not possibly grow larger than that and
# ideally will be much smaller than that.
foreach $string1 (@failures) {
$string2 = $pairs[$all];
# get string1 from the Failures array and parse it up into the
# @compare1 array
# get string2 from the current configure option and parse it into
# @compare2 array
my @compare1 = split(' ', $string1);
my @compare2 = split(' ', $string2);
# loop through both arrays storing each element in var1 and var2
# for comparing
foreach my $var1 (@compare1) {
foreach my $var2 (@compare2) {
#see if var1 and var2 match
if ($var1 eq $var2) {
print "ALERT!!!!\n";
print "string1 is: \"$string1\"\n";
print "string2 is: \"$string2\"\n\n";
print "found match string1 contains $var1 and string2 contains $var2\n\n";
$reject = 1;
}
}
}
}
if ($reject eq 1) {
print "\n$string2\n";
print "didn't run this test because it's been rejected\n\n";
# reset the reject flag
$reject = 0;
}
else {
print "\n$string2\n";
print "This test did run\n\n";
}
$all = $all + 1;
####################################################
## End test case
##... Rest of script
}
运行输出:
ALERT!!!!
string1 is: "--configure-option2 --configure-option5"
string2 is: "--configure-option1 --configure-option2 --configure-option3 --configure-option4"
found match string1 contains --configure-option2 and string2 contains --configure-option2
--configure-option1 --configure-option2 --configure-option3 --configure-option4
didn't run this test because it's been rejected
--configure-option3 --configure-option4 --configure-option12
This test did run