我有一个哈希,用FACD,BDCD,DDSE,CDSD等键说“标识符”。我想通过考虑X来匹配任何字母数字来搜索键“ FXXD”是否存在于哈希“标识符”中。在这种情况下,考虑到X可以是任意值,因此应该返回“ FXXD”与“ FACD”匹配。
可以通过添加字符来匹配任何东西来完成哈希键搜索吗?
有什么主意真的有用吗?
预先感谢!
答案 0 :(得分:5)
选择符合模式的键
my @spec_keys = grep { /F..D/ } keys %identifier;
F..D
模式可以在键中的任何位置。如果它应该与键匹配且没有任何前导或结尾字符,则将其锚定/^F..D$/
。
答案 1 :(得分:5)
首先,将字符串中的X转换为与单个字母数字字符匹配的正则表达式字符类,然后再转换旧的grep
/ keys
:
#!/usr/bin/perl
use warnings;
use strict;
use feature qw/say/;
my $test = { FACD => 1, BDCD => 1, DDSE => 1, CDSD => 1, QFADD => 1 };
sub matches {
my ($hash, $key) = @_;
# X matches all alphanumeric characters
$key =~ s/X/[[:alnum:]]/g;
my $pat = qr/^$key$/;
return grep { m/$pat/ } keys %$hash;
}
for (qw/FXXD FXDD BXXX/) {
say $_, (matches($test, $_) ? " matches!" : " doesn't match!");
}
答案 2 :(得分:1)
不,你不能。对于这种搜索,单个哈希是错误的方法。
如果您的密钥是固定大小的,例如根据您的示例,最多4个字符,您可以使用多个哈希。这是算法的草图:
my %first = (
A => { AAAA => 1, ... all keys starting with A... },
...
);
my %second = {
A => { AAAA => 1, ... all keys having A as 2nd character... },
...
);
my %third = ...
my %fourth = ...
# match first (F) and last (D) character in key
my $matches_first = $first{F};
my $matches_last = $fourth{D};
my @matches =
grep { exists $matches_fourth->{$_} }
keys %{ $matches_first };
在真实程序中,您将从键列表中生成%first
等的内容,并从搜索模式中计算匹配代码。
foreach my $c ('A'..'Z') {
$first{$c} = {};
$second{$c} = {};
$third{$c} = {};
$fourth{$c} = {};
}
foreach my $key (keys %identifier) {
my($c1, $c2, $c3, $c4) = split(//, $key);
$first{$c1}->{$key}++;
$second{$c2}->{$key}++;
$third{$c3}->{$key}++;
$fourth($c4}->{$key}++;
}
编辑2:根据您的数据量,也可以使用简单的搜索功能,例如以您为例
my @matches = grep { /^F..D$/ } keys %identifier;
答案 3 :(得分:1)
如果您不太关心效果,可以使用Tie::Hash::Regex。
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Tie::Hash::Regex;
my %hash : Regex;
%hash = (
FACD => 1,
BDCD => 1,
DDSE => 1,
CDSD => 1,
);
if (exists $hash{'F\w\wD'}) {
say 'Found key matching FXXD';
} else {
say 'No key matching FXXD';
}
[完整披露-我将此模块编写为愚蠢的捆绑演示。我真的不建议您在生产中使用它。]