I'd like to use a "compiled regex" (I mean: an expression in the form qr/../
) as a key for an hash structure.
To discern between constant strings and these regexes when iterating over the hash keyes, I was trying to use ref()
, or is_regexp()
, but the former returns a null string, and the latter doesn't work. I'm afraid I'm missing something fundamental about Perl refs vs. scalars.
Apart from that, my solution seems to work. Is it too ugly anyway? Any alternate proposal is welcome.
Some code to understand ref()
function:
my $regex = qr/foo/;
printf "ref(\$regex): %s \n", ref($regex);
printf "is_regexp(\$regex): %d \n", is_regexp($regex);
# ref($regex): Regexp
# is_regexp($regex): 1
my $scalar = 3;
printf "ref(\$scalar): [%s] \n", ref($scalar);
# ref($scalar): []
my %my_hash = ('name', 'Becky', 'age', 23);
for my $k (keys %my_hash) {
printf "%s [%s] -> %s [%s] \n", $k, ref($k), $my_hash{$k}, ref($my_hash{$k});
}
# name [] -> Becky []
# age [] -> 23 []
First of all, unlike encryption, hashing is always one way. In fact, hashing is often called "one way encryption". So, while you can decrypt an encrypted text, you cannot "de-hash" a hashed text.
$1$ is the prefix used to identify md5-crypt hashes, following the Modular Crypt Format. salt is 0-8 characters drawn from the regexp range [./0-9A-Za-z] ; providing a 48-bit salt ( 5pZSV9va in the example).
About the Hash Analyzer The tool can look at the characters that make up the hash to possibly identify which type of hash it is and what it may be used for. Hash types this tool can positively identify: MD5. SHA1 (SHA128)
Software to identify the different types of hashes used to encrypt data and especially passwords. Installed size: 49 KB.
As Qtax notes in the comments, Perl hash keys are always strings: if you use something other than a string as a hash key, it's first converted to a string.
In another comment you write:
"I read counter definitions from a config file; I want to be able to support some pattern syntax, for example: McDouglas, McDonald, /Mc[A-Za-z]*/. I then read counter values from text files, and I update relevant counterS accordingly: McDonald 23 McIntosh 11"
If I understand this right, one simple solution might be to to store the compiled regexps in another hash, keyed on their string representation:
my @patterns = (
'McDouglas',
'McDonald',
'Mc[A-Za-z]*',
);
my %regexps = map +($_ => qr/^$_$/), @patterns;
my %counters;
while (<>) {
while (my ($pat, $re) = each %regexps) {
$counters{$pat}++ if /$re/;
}
}
foreach my $pat (@patterns) {
print "$pat: ", ($counters{$pat} || 0), "\n";
}
Is there anything wrong with using Tie::RegexpHash
? It saves you from having to reinvent the wheel :)
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With