I now know you want to distinguish between data matching one of two kinds of sources, it either equals this hash key string (if it's supposed to be treated as a string) or matches the regexp (if it represents a regexp) — the above hash is a kind of dispatch table, originally just matching literal strings, and now he has to extend it to match using a pattern — preferably in a backward compatible way. But you can't distinguish between strings and regexes in hash keys any more, since every hash key is nothing but a string.
One approach I prosposed is to always use a regexp for the hash keys, converting strings to a regexp using quotemeta and string start/end anchors. That way you don't have to make the distinction. But that involves recompiling the regex every time you want to do a test. Not so good.
So another approach is to have an extra caching hash, that maps these string keys to, well, whatever you like. I suggest you use something looking like globs on the left, because it's probably easier for maintenance, eventually converting them to the equivalent regexp by code — once.
Now you can make the distinction you asked about, in the values of this hash. And regexps remain Regexps.my %process = ( 'foo*' => qr/^foo.*$/, foo => 'foo' );
As a sample converter of glob to regexp, you can do something like this:
{ my %replace; sub glob_to_regexp { my $pattern = shift; %replace or %replace = ( '*' => '.*', '?' => '.' ); $pattern =~ s/(\W)/ $replace{$1} || quotemeta($1)/ge; return qr/^$pattern\z/; } }
Of course, you can implement more advanced glob features if you like, patching the convertor code accordingly.
In reply to Re: Compiled regex as hash key vs. string?
by bart
in thread Compiled regex as hash key vs. string?
by blahblah
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |