识别哈希键的“类型”

时间:2012-03-05 11:36:32

标签: regex perl data-structures

我想使用“编译的正则表达式”(我的意思是:qr/../形式的表达式)作为哈希结构的键。

在迭代哈希键时,为了识别常量字符串和这些正则表达式,我试图使用ref()is_regexp(),但前者返回空字符串,而后者不返回工作。我担心我会遗漏一些关于Perl refs和scalars的基本信息。

除此之外,我的解决方案似乎有效。反正太难看了吗? 欢迎任何替代提案。

了解ref()函数的一些代码:

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 []

2 个答案:

答案 0 :(得分:7)

正如Qtax在评论中指出的那样,Perl哈希键是总是字符串:如果你使用字符串以外的东西作为哈希键,它首先被转换为字符串。

在另一条评论中写道:

  

“我从配置文件中读取计数器定义;我希望能够支持一些模式语法,例如:McDouglas,McDonald,/ Mc [A-Za-z] * /。然后我从文本中读取计数器值文件,我相应更新相关的反制品:麦克唐纳23麦金托什11“

如果我理解这一点,一个简单的解决方案可能是将已编译的正则表达式存储在另一个哈希中,并键入其字符串表示形式:

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";
}

答案 1 :(得分:2)

使用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"