in reply to Matching arrays?

Regexes work on scalars (individual variables), not on whole arrays at a time.

However, perl comes to the rescue with it's built-in grep function

#! perl -slw use strict; my @text = ( "Hi there 11", "Fred blamed me", "17 o clock", "It's snowing hampsters", "Pickles are people too!" ); if ( grep( /11/, @text ) || grep( /are/, @text ) ) { print "test successfull"; } else { print "We messed something up again"; }; __END__ P:\test>334482 test successfull

This asks grep to scan each element in the array and pass through only those that match the regex.

However, in a scalar context, it returns not the elements themselves, but a count of those that matched. If the number matched is non-zero, then the if statement will be true.

Once you've got that working, you will see that there is no need to scan the whole array twice, as you can put both regexes into the same grep and look for them both in one pass.

if ( grep( /11/ || /are/, @text ) ) { print "test successfull"; } else { print "We messed something up again"; };

In this case, it is also possible to remove the need to match against each string twice, by combining the search terms into a single regex.

if ( grep( /(11|are)/, @text ) ) { print "test successfull"; } else { print "We messed something up again"; };

Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail

Replies are listed 'Best First'.
Re: Re: Matching arrays?
by bageler (Hermit) on Mar 06, 2004 at 16:21 UTC
    It should be noted that grep(/11/||/are/,@text) will be quite a bit faster in execution than grep(/11|are/),@text) because of the short circuit and constant regexpes.

    Indeed, after a quick test I found:
    #!/usr/bin/perl use Benchmark qw(timethese cmpthese); my @seed = ("Hi there 11", "Fred blamed me", "17 o clock", "It's snowi +ng hampsters", "Pickles are people too!"); @text = map {@seed[$_ % $#seed+1]}(0 .. 300); cmpthese -1 => { short_circuit => 'grep(/11/||/are/,@text)', alternate => 'grep(/11|are/,@text)', } __END__ bagelbox:~ josh$ perl testgrep Rate alternate short_circuit alternate 642/s -- -81% short_circuit 3309/s 416% --
      I'd think that after a certain number of alternates the regex would be faster.
Re: Re: Matching arrays?
by Anonymous Monk on Mar 06, 2004 at 12:14 UTC
    Weird, I just tried writing a full string of text with numbers in it and I tried using the same expression I wrote in my original node (except I used a scalar instead of array) and it still failed. If making multiple tests to see if atleast one of a few phrases are present in a string, what's wrong with my original code?
      what's wrong with my original code

      You original code below:
      if (@text =~ /11/ || @text =~ /are/) { ...

      Ok, the problem with your code is that you are operating the array text in scalar context, which is the number of elements in the array. So you code is actually doing this:
      if ('5' =~ /11/ || '5' =~ /are/) { ...

      And of cause it will not match anything.

      and it still failed.

      Please show us the code.

      What you are saying is the following:

      my $text = "Hi there 11 Fred blamed me 17 o clock It's snowing hampste +rs Pickles are people too!; if ($text =~ /11/ || $text =~ /are/) {

      This snippet will work. What did you do?

      #!/usr/bin/perl use strict; my $check; my @text = ("Hi there 11", "Fred blamed me", "17 o clock", "It's snowi +ng hampsters", "Pickles are people too!"); foreach (@text) { if ( /11/ || /are/) { print "test successful"; $check++; } } unless ($check) { print "test failed"; }
      of course you should also use strict!!
        BTW, that code will return "test failed" not because it is incorrect, but because the strings don't contain what you're matching for...