开发者

perl pattern match array

开发者 https://www.devze.com 2023-02-10 19:43 出处:网络
I want to match a string I read against an array of possible matches.Would also be good if it could return the index of the match string. I COULD hard code easily enough ... and probably will for expe

I want to match a string I read against an array of possible matches. Would also be good if it could return the index of the match string. I COULD hard code easily enough ... and probably will for expediency this time around, but for general case, I'd like to see if this is possible. I've looked through some books and online (including stackoverflow), but can't find what I'm looking for and can't quite connect the dots to figure it out myself.

Here's an example of the general kind of thing I'm looking for ... of course it does not work, which is why I am asking for help. But I hope it is sufficient to infer my intent.

Example:

my $patterns;
my $line;

my $c = 0 ;
$patterns{$c++} = "$exact" ;  # where the $ i开发者_如何学Cn $exact marks the beginning of line.
$patterns{$c++} = "$T?:" ;    # where the ? is the normal wildcard
$patterns{$c++} = "" ;
$patterns{$c++} = "exact" ;

open (FILE, "example.txt") || die "Unable to open file.\n";

while (my $line = <IN>) {

  my $idx = -1;
  for ($i=0; $i<$c :$i++) {
    if ($line =~ /$patterns{$i}/ ) { $idx = $i ; }
  }

  $result = $idx;  # of course this will return index of last pattern match, but that's ok
}
close(FILE);


Without knowing exactly what you are looking for, this is your code transformed into actual Perl code.

use warnings;
use strict;
use autodie; # open and close will now die on failure
use 5.10.1;

my @patterns = (
  qr"^exact",
  qr"^T.?:",
  "",
  "exact",
);

my $result;

open my $fh, '<', 'example.txt';

while ( my $line = <$fh> ) {
  chomp $line;
  $result = $line ~~ @patterns;
}
close($fh);


Alternately, if you're using perl 5.8 rather than 5.10, Regexp::Assemble will handle this for you:

use strict;
use warnings;
use autodie; # open and close will now die on failure

my @patterns = (
  qr"^exact",
  qr"^T.?:",
  "",
  "exact",
);

my $ra = Regexp::Assemble->new;
$ra->add(@patterns);

my $result;

open my $fh, '<', 'example.txt';

while ( my $line = <$fh> ) {
  chomp $line;
  $result = $ra->match($line);
}
close($fh);

R::A can also be set to tell you which of the original patterns matched, which I don't think the 5.10 smart match operator (~~) can do, but that will give you the actual pattern (exact) rather than its index (3). If you really need the index, you'll either need to loop over the patterns testing each in order (which is likely to have a significant performance impact if you have many patterns) or build a pattern => index hash and use that to look up the index of the matched pattern.

0

精彩评论

暂无评论...
验证码 换一张
取 消