比较字符串的标记与字符串数组的标记

时间:2015-07-30 18:20:31

标签: arrays regex perl substring

我有一个字符串,其中包含以空格分隔的标记列表。

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

4 个答案:

答案 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