获取Perl哈希键是否没有循环的字符串/正则表达式的一部分?

时间:2015-05-12 09:36:05

标签: regex perl hash

我甚至不确定如何在一行中说出问题,这就是我需要的:

我需要获取一个哈希键的元素,即" subset"一个给定的字符串。所以,如果我的哈希是

%h = ( 'ab' => 1, 'cd' => 2);

,字符串为abc123,我会从哈希中获得ab

我知道我能做到

$str = 'abc123';
foreach (keys %h) {
    print "$_ \n" if $str =~ m/^$_/;
}

但是我问是否有更有效的方法,比如如果我像其他方式匹配那样会起作用

%h = ('abc123' => 1, 'def456' => 2);
print "$_ \n" for grep /^ab/, keys %h

3 个答案:

答案 0 :(得分:1)

简短回答 - 不,不是真的。如果不检查每个子字符串,则无法找到匹配的子字符串。 formap没有获得效率他们无论如何都会在幕后隐式循环。

但是可能会通过提前编译正则表达式来提高效率 - 请参阅http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators - 因为它们是静态的。

答案 1 :(得分:1)

您可以在调用grep时隐藏循环,如第二个示例

my %h = ( ab => 1, cd => 2 );
my $str = 'abc123';

print "$_\n" for grep { $str =~ /^$_/ } keys %h;

但可能很少或没有速度优势

如果您只想找到一个的哈希键,那么您可以从它们构建一个正则表达式,就像这样

my $re = join '|', sort { length($b) <=> length($a) } keys %h;
$re = qr/$re/;

然后找到第一个匹配的哈希键,如下所示

print "$1\n" if $str =~ /^($re)/;

答案 2 :(得分:-1)

map {print "$_ \n" if $str =~ m/^$_/;} keys(%h);