Perl - 使用正则表达式过滤哈希表中匹配键名的条目(不使用智能匹配)

3
我需要基于正则表达式过滤哈希,如果正则表达式匹配,则从哈希中删除键。
这是我目前得到的代码,不幸的是它什么也没做,我不知道为什么。
因此,我正在使用字符串数组构建正则表达式,我还需要匹配子字符串,因此如果哈希键是someprefix_somestring,我需要将其与somestringstring进行匹配。
my $hashref = {someprefix_somekey => 'somevalue', otherprefix_otherkey => 23, otherprefix_somekey => 'someothervalue'};
my @array_of_strings = ('somekey', 'strings', 'bits', 'bobs');

my $regex = join( '|', sort { length( $b ) <=> length( $a ) or $a cmp $b } @array_of_strings );
$regex    = qr{($regex)};

delete $hashref->{ grep { !m/$regex/ } keys %$hashref };

我期望$hashref之后的样子像这样:{otherprefix_otherkey => 23},因为someprefix_somekeyotherprefix_somekey会匹配$regex并从哈希表中删除。

我不知道为什么它没有起作用,请给我指点

感谢hobbs的答案,我现在能够解决它了,这就是我现在拥有的:

my $hashref = {someprefix_somekey => 'somevalue', otherprefix_otherkey => 23, otherprefix_somekey => 'someothervalue'};
my @array_of_strings = ('somekey', 'strings', 'bits', 'bobs');

my $regex = join( '|', sort { length( $b ) <=> length( $a ) or $a cmp $b } @array_of_strings );
$regex    = qr{($regex)};

delete @{$hashref}{grep { m/$regex/ } keys %$hashref };
1个回答

7
你的delete语句不太正确,因为你在使用符号来访问单个键,因此grep以标量上下文运行。这意味着如果有三个键不匹配你的正则表达式,最终你尝试做的事情就像 delete $hashref->{'3'}
如果你将最后一行改为这样,它应该可以工作:
delete @{$hashref}{grep /$regex/, keys %$hashref };

使用哈希切片。如果您认为这种语法太难看,您也可以。
delete $hashref->{$_} for grep /$regex/, keys %$hashref;

这可能会更自然一些。


2
是的,但是OP想要保留不匹配的内容,所以您应该删除grep可以找到的所有条目,而不使用“!”。 - Birei
2
哈希切片是 Perl 中一种被低估的工具。 - Joe Z
切片应该只用于简单的事情。迟早有些维护者会用foreach循环替换上面的代码。编写您的代码,使其易于维护。"不要聪明过头",达米安·康威,《Perl最佳实践》http://oreilly.com/perl/excerpts/perl-best-practices/appendix-b.html - shawnhcorey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接