1

I am trying to create a hash where the keys are regular expressions and the values are substitutions. I have done this in a MySQL database creating a similar structure and using a query such as "select * from table where $lookup RLIKE `key`" and it works fine. I am wanting to try the same in a perl script to see if I can make it run more efficiently. I realize I could make this a loop and check each key but don;t want that which is why I built the regex string. The only part I cannot figure out is how to get perl to give me back the part of the regex (the alteration) that matched...

%s = (
  '^mynumbers-(\d+)$' => 'thenumber-$1' ,
  '^myletters-([a-zA-Z])$' => 'theletter-$1'
);

#build a string of the hash keys into a regex
while (keys %s) {
  $regex_string.="($_)|";
}

#this is the input that will be looked up
$lookup = 'mynumbers-123';

if ($lookup=~/$regex_string/) {

  print "found->$lookup in the regex\n";

  $matched_regex = $i_dont_know; 
  ### How do I know which subgroup it matched???

  ### I need to know so I can do this
  $lookup=~s/\Q$i_dont_know\E/\Q$s{$matched_regex}\E/;
}
4

1 回答 1

3

正如 daxim 指出的那样,有几个 CPAN 模块可以满足您的需求。Tie::RegexpHash是其中之一:

概要

use Tie::RegexpHash;

my %hash;

tie %hash, 'Tie::RegexpHash';

$hash{ qr/^5(\s+|-)?gal(\.|lons?)?/i } = '5-GAL';

$hash{'5 gal'};     # returns "5-GAL"
$hash{'5GAL'};      # returns "5-GAL"
$hash{'5  gallon'}; # also returns "5-GAL"

my $rehash = Tie::RegexpHash->new();

$rehash->add( qr/\d+(\.\d+)?/, "contains a number" );
$rehash->add( qr/s$/,          "ends with an \`s\'" );

$rehash->match( "foo 123" );  # returns "contains a number"
$rehash->match( "examples" ); # returns "ends with an `s'"
于 2012-06-03T12:54:38.290 回答