in reply to Finding out which of a list of patterns matched

You could capture the match (read perldoc perlre on capturing brackets) and use the capture result to determine your program flow. One elegant way of doing this is to use a hash with the possible matches as hash keys, and the corresponding actions as the hash values in a subroutine reference (this is commonly called a "dispatch table"):

#!/usr/bin/perl use warnings; use strict; use Carp; my $input = shift or croak "Give me an argument, fool!\n"; my %action = ( foo => sub { print "fooing\n" }, bar => sub { print "barred\n" }, baz => sub { print "all bazzed out\n" }, ); if (my ($match) = $input =~ m/(foo|bar|baz)/ ){ &{$action{$match}}; } else { croak "Dunno what to do\n"; }

There are ten types of people: those that understand binary and those that don't.

Replies are listed 'Best First'.
Re^2: Finding out which of a list of patterns matched
by lemnisca (Sexton) on Jan 23, 2006 at 00:50 UTC
    Unfortunately I'm not sure that this will be able to work with my patterns. I'll be reading the patterns in from another file, not creating them myself, and they could be arbitrarily complex - not necessarily a simple word to match like 'foo' which means I don't think the matching text will be much good for a key to a hash. Sorry if I misled you on that point in my original post - I should have given a better example of the pattenrs.

      The unasked question here is: Once you have the match, how will you determine what action to take?

      If you are reading the patterns to be matched from a separate file prepared by someone else, how do they indicate what action should be taken? Or how do you decide what action should be taken for each pattern matched?

      could be arbitrarily complex - ... I don't think the matching text will be much good for a key to a hash.

      The matching text may not be a good key as it wouldn't match a hash key that was a non-constant regex, but using $#- will tell you which pattern was matched, and could be used as an index to an array containing the original patterns to retrieve the one that matched (rather than the text it matched).

      Eg.

      my @patterns = slurp( 'file' ); my %dispatch; @dispatch{ @patterns } = ( ??? ); my $regex = '(', join( ')|(', @patterns ) . ')'; while( my $data = <DATA> ) { if( $data =~ $regex ) { $dispatch{ $patterns[ $#- ] }->( $1 ); } }

      The problem with the above code is what to substitute for '???'. Ie. What action is required for matches against each pattern. But that problem exists whether you are using a dispatch table; an if/else cascade or any other mechanism. Of the choices available the dispatch table is by far the easiest--if not the only--option for the dynamic search patterns you describe.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.