perlnewbie9292 has asked for the wisdom of the Perl Monks concerning the following question:

Hello, Hoping to get an idea as to the best way to approach the problem that I am having. I am trying to search an array for a list of strings which I can keep in an array or as individual variables. I need all SEARCH strings to EXIST/MATCH within the array that I am searching against and only print if the entire list or search strings are found. For example this is what I tried with no luck.
#!/usr/bin/perl use strict; use warnings; #Data contained in the TXT File ARRAY my @dataArray = ("12/12-08:01:22.360401 *** [945850] pr0", "12/13-08:03:22.420449 *** [948851] pr1", "12/16-08:04:22.439726 *** [948852] pr0", "12/17-08:10:22.440649 *** [948853] pr1", "12/17-08:10:22.444688 *** [948854] pr1", "12/17-08:10:22.512471 *** [948855] pr2", "12/17-08:10:22.512471 *** [948856] pr0", "12/17-08:10:22.527738 *** [948857] pr1", "12/17-08:10:22.527888 *** [948858] pr3", "12/17-08:10:22.527898 *** [948859] pr2", "12/17-08:10:22.527999 *** [948860] pr2", "12/17-08:10:22.528999 *** [948861] pr2", "12/17-08:10:22.529999 *** [948862] pr2" ); #Search strings that MUST match - non ARRAY my $searchString1 = "[945850]"; my $searchString2 = "[945851]"; my $searchString3 = "[945852]"; #Search strings that must much - ARRAY form. my @arrayOfSearchStrings = ( "[945850]", "[945851]", "[945852]", ); for my $data ( @dataArray ) { my @splits = split(/ /, $data); my @value = $splits[3]; for ( @value ) { if ( $_ == "$searchString1" && $_ == "$searchString2" +&& $_ == "$searchString3" ) { #if ( $_ =~ /[945850] && [945851] && [945852]/gm ) { #Print Found only if all the defined search #strings are found in the array, no match #if all do not exist within the array print "Found ALL SEARCH STRINGS required in AR +RAY\n"; } else { print "Did not find all needed search strings\ +n"; } } }
For example: I only want to **print "Found ALL SEARCH STRINGS required in ARRAY\n";** if ALL three of my searchStrings [945850], [945851] and [945852] are in the @dataArray. If all of the search strings don't exist in the array print "Did not find all needed search strings\n"; Thanks for the help in advanced.

Replies are listed 'Best First'.
Re: Search an array for array of strings
by jethro (Monsignor) on Dec 22, 2010 at 17:58 UTC
    my $data= join("\t", map { /(\[\d*\])/ } @dataArray); my $notfound=0; foreach (@arrayOfSearchStrings) { if (not $data=~/\Q$_\E/) { $notfound=1; print "$_ not included\n"; last; } } print "All there\n" unless $notfound;

    Basically I construct a string with all numbers in dataArray concatenated and then check for every number if it is in there. Might get a bit slow when @dataArray gets really huge. But then you could use a hash instead to store the dataArray numbers.

    The \t is only there to prevent matching parts of two consecutive numbers. That can't happen as long as your numbers have brackets around them, but it is just a bit safer against future changes

    \Q\E in the regular expression is there because brackets are special characters in regexes (that's why I also escape them in the first regex). And even when they are "hidden" in variables they need to be escaped and that's what \Q...\E does

Re: Search an array for array of strings
by toolic (Bishop) on Dec 22, 2010 at 18:00 UTC
    You could use a hash to keep track of which search strings have been found (but you need to make sure the strings are unique):
    use strict; use warnings; #Data contained in the TXT File ARRAY my @dataArray = ("12/12-08:01:22.360401 *** [945850] pr0", "12/13-08:03:22.420449 *** [948851] pr1", "12/16-08:04:22.439726 *** [948852] pr0", "12/17-08:10:22.440649 *** [948853] pr1", "12/17-08:10:22.444688 *** [948854] pr1", "12/17-08:10:22.512471 *** [948855] pr2", "12/17-08:10:22.512471 *** [948856] pr0", "12/17-08:10:22.527738 *** [948857] pr1", "12/17-08:10:22.527888 *** [948858] pr3", "12/17-08:10:22.527898 *** [948859] pr2", "12/17-08:10:22.527999 *** [948860] pr2", "12/17-08:10:22.528999 *** [948861] pr2", "12/17-08:10:22.529999 *** [948862] pr2" ); #Search strings that must much - ARRAY form. my @arrayOfSearchStrings = map { "[$_]" } 945850 .. 945852; my %found; for (@dataArray) { for my $pat (@arrayOfSearchStrings) { $found{$pat}++ if /\Q$pat/; } } if (@arrayOfSearchStrings == (keys %found)) { print "Found ALL SEARCH STRINGS required in ARRAY\n"; } else { print "Did not find all needed search strings\n"; } __END__ Did not find all needed search strings

    Update: This may be faster since it stops looking though the dataArray as soon as it finds all your search strings:

    #Search strings that must much - ARRAY form. my @arrayOfSearchStrings = map { "[$_]" } 945850 .. 945852; my %searchStrings = map { $_ => 1 } @arrayOfSearchStrings; OUTER: for (@dataArray) { for my $pat (keys %searchStrings) { if (/\Q$pat/) { delete $searchStrings{$pat}; last OUTER unless %searchStrings; } } } if (%searchStrings) { print "Did not find all needed search strings\n"; } else { print "Found ALL SEARCH STRINGS required in ARRAY\n"; }
Re: Search an array for array of strings
by andmott (Acolyte) on Dec 22, 2010 at 18:05 UTC

    First I think you may need to change line #36 to use the operator 'eq' instead of '==', the latter of which is used only for numbers. So maybe instead something like this when dealing with strings...

    if ( $_ eq "$searchString1" && $_ eq "$searchString2" && $_ eq "$searc +hString3" )

    I'm not familiar with using logical && within a regular expression. I don't think it is supported unless on the eval side of a substitution. You might re-write your regular expression like this on line 37

    if ( /[945850]/gm && /[945851]/gm && /[945852]/gm )

    However there looks like there may be other errors in your code causing this to fail. Let me look at it some more and write up something.

Re: Search an array for array of strings
by JavaFan (Canon) on Dec 22, 2010 at 18:33 UTC
    Something like:
    use 5.010; my @searches = qw/[945850] [945851] [945852]/; my $found = 1; foreach my $s (@searches) { $found &&= /\Q $s / ~~ @dataArray; } say $found ? "Found ALL SEARCH STRINGS required in ARRAY" : "Did not find all needed search strings";