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

Using a regex for matching, is there an easier way to pass a whole bunch of tests at once instead of
foreach my $line (@lines) { next if ($line !~ m/red/ || $line !~ m/blue/ || $line =~ m/green/) +; }

Replies are listed 'Best First'.
Re: quick regex help for multiple OR
by dragonchild (Archbishop) on May 13, 2008 at 00:50 UTC
    my $regex = join '|', qw( red green blue ); foreach my $line ( @lines ) { next if $line !~ $regex; }

    Update: toolic pointed out that the conditions were different for the different colors. A better version would be:

    my $negative_regex = join '|', qw( red blue ); my $positive_regex = join '|', qw( green ); foreach my $line ( @lines ) { next if $line =~ $positive_regex || $line !~ $negative_regex; }

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      thanks Dragonchild, this looks like good solution.

      Didn't realize you can do that w/ regex
      Just wanted to add that, OP should be using below as well.
      next unless $line =~ $regex;
        s/should/could/;

        That's a matter of personal preference.
        In PBP, TheDamian recommends avoiding the use of unless. Mainly because statements can very quickly become quite difficult to read if you start extending them and adding multiple conditions.

        I tend to agree with this view, but as I say - it's really a matter of personal preference.

        Cheers,
        Darren :)

Re: quick regex help for multiple OR
by mwah (Hermit) on May 13, 2008 at 17:34 UTC

    The stated problem is not exactly regexp friendly ;-) (to be solved in a single expression), as has been stated by others.

    You are looking for a combination of conditions, a problem which might be solved better per parser or similar stuff.

    BTW, you can set conditions during the regexp run and jump on the result afterwards. This might be handy if you have several conditions which depend linearly on the input data, sth. like:

    ... our $c; my $regex = qr{ red (?{$c|=4}) | green (?{$c|=2}) | blue (?{$c|=1}) }x; foreach my $line (@lines) { $c = 0; next if () = $line =~ /$regex/g, $c != 5; # bail on: !(red && bl +ue) | green # do something here, got red/blue combo }

    Regards

    mwa