如何通过匹配字符的任何字母/数字来检查哈希中是否存在哈希键{say X}

时间:2019-01-13 07:02:53

标签: perl

我有一个哈希,用FACD,BDCD,DDSE,CDSD等键说“标识符”。我想通过考虑X来匹配任何字母数字来搜索键“ FXXD”是否存在于哈希“标识符”中。在这种情况下,考虑到X可以是任意值,因此应该返回“ FXXD”与“ FACD”匹配。

可以通过添加字符来匹配任何东西来完成哈希键搜索吗?

有什么主意真的有用吗?

预先感谢!

4 个答案:

答案 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';
}

[完整披露-我将此模块编写为愚蠢的捆绑演示。我真的不建议您在生产中使用它。]

相关问题