我想知道Perl是否有内置的方法来检查是否存在一个哈希元素,其中一个键与特定的正则表达式匹配。例如:
my %h = ( 'twelve' => 12, 'thirteen' => 13, 'fourteen' => 14 );
我想知道是否有办法做到这一点:
print "We have 12\n" if exists $h{twelve};
print "We have some teens\n" if exists $h{/.*teen$/};
答案 0 :(得分:24)
smart match operator执行此操作(自Perl v5.10起可用)。
$a $b Type of Match Implied Matching Code
====== ===== ===================== =============
...
Regex Hash hash key grep grep /$a/, keys %$b
...
样本用法:
# print if any key in %h ends in "teen"
print "We have some teens\n" if /.*teen$/ ~~ %h;
答案 1 :(得分:12)
除了这里的其他答案,您还可以使用perl的grep:
print "We have some teens\n" if grep {/.*teen/} keys %h;
答案 2 :(得分:6)
是的,它被称为:
use List::Util qw<first>;
# Your regex does not compile perhaps you mean /teen$/
my $value = $hash{ ( first { m/teen/ } keys %hash ) || '' };
(在智能比赛之前,就是这样。看看小偷的智能比赛答案。)
您还可以对键进行排序:
my $value = $hash{ ( first { m/teen/ } sort keys %hash ) || '' };
我会将其冻结为“操作”:
use Scalar::Util qw<reftype>;
sub values_for_keys_like (\[%$]$) {
my $ref = reftype( $_[0] ) eq 'HASH' ? $_[0] : $$_[0];
return unless my @keys = keys %$ref;
my $regex = shift;
# allow strings
$regex = qr/$regex/ unless my $typ = ref( $regex );
# allow regex or just plain ol' filter functions.
my $test = $typ eq 'CODE' ? $regex : sub { return unless m/$regex/; 1 };
if ( wantarray ) {
return unless my @k = grep { defined $test->( $_ ) } @keys;
return @$ref{ @k };
}
else {
return unless my $key = first { defined $test->( $_ ) } @keys;
return $ref->{ $key };
}
}
你可以像这样使用它:
my $key = values_for_keys_like( %hash => qr/teen/ );
或
my $key = values_for_keys_like( $base->{level_two}{level_three} => qr/teen/ );
答案 3 :(得分:4)
没有内置方式,但CPAN上有Tie::Hash::Regex
。