【问题标题】:print hash keys and values if they are matched如果匹配,则打印哈希键和值
【发布时间】:2015-04-25 01:51:10
【问题描述】:

我正在尝试将哈希与文件匹配。但是,由于标点符号和空格,我正在搜索的内容与文件不完全匹配。例如,我的哈希中可能有“JE Industries, Incorporated”,而我的文件中可能有“JE Industries Incorporated”。由于“,”,逗号,这两个显然不匹配。

所以我的解决方案是有一个散列和一个文件并对每个文件执行修改(替换文件和散列值中的标点符号,以便“JE Industries, Incorporated”与“JE Industries Incorporated”以及其他一组规则。)一旦满足匹配,就转到针对文件的哈希中的下一项。如果该匹配不满足,请转到下一个规则“elsif”,并尝试匹配该匹配,如果满足,请转到下一项等。我还想要一个未修改的哈希和行副本,以便每个原件都没有修改。所以基本上一次只应用一个规则。

所以我一直在研究如何解决这个问题,但结果不是我想要的。

代码

 open(my $fh, "list.txt");

    while(<$fh>) {
     my($line) = $_;
     chomp($line);
    my %hash = (
        12345 => 'JE Industries, Incorporated',
        123355 => 'Josh Industries, Inc'
    );
    while( my( $key, $value ) = each %hash ) {
    if($value =~ s/[[:punct:]]//gi eq $line =~ s/[[:punct:]]//gi) {print $line,",",$key,"\n";} #replace punctuation on both $line and $value to make them match##
    elsif($value =~ s/[\s]//gi eq $line =~ s/[\s]//gi) {print $value,",",$key,"\n";} ## if punctuation does not do it replace space##

}
}

我的文件,list.txt

JE 工业公司
乔什工业公司
吉姆鲍勃公司

我的输出

JE Industries Incorporated,123355
乔希工业公司,123355

期望的输出

JE Industries Incorporated,"JE Industries, Incorporated",12345
乔什工业公司,“乔什工业公司”,123355

original_Value_from_file,"original_Value_from_hash",每个对应的key

它将我的项目从哈希匹配到文件,但是,它只是为每个值分配哈希中的最后一个键。另外,我有点不确定如何打印每行/哈希的原始形式以及匹配结果。还要记住,对于修改,我想从一开始就为每个规则修改它们。换句话说,在第二条规则发生的地方,“$value =~ s/[\s]//gi eq $line =~ s/[\s]//gi”,我想在“JE Industries , Incorporated”不在“JE Industries Incorporated”中。

最后我希望我的结果是从哈希值匹配的原始形式,$line 值的原始形式,以及它们对应的哈希键。我还希望实施更多规则,而不仅仅是省略标点和空格以进行更紧密的匹配。

【问题讨论】:

    标签: perl hash matching fuzzy-search


    【解决方案1】:

    很多时候提前准备数据会更容易。 为了让你的代码以后更简单。

    这是我要做的,为 id 创建一个非标点名称的反向哈希。

    循环文件时,我只需要将我的非标点符号与 id hash 进行比较即可找到匹配项。

    下面的工作示例

    use strict;
    use warnings;
    my %id_to_name = (
        12345  => 'JE Industries, Incorporated',
        123355 => 'Josh Industries, Inc'
    );
    #Create a reverse map with out any punctuation
    my %no_punc_name_to_id;
    while (my ($key, $value) = each %id_to_name) {
        $value =~ s/[[:punct:]]//gi;
        $no_punc_name_to_id{$value} = $key;
    }
    my $filename = 'list.txt';
    open my $fh , '<' , $filename or die "Cannot read '$filename': $!";
    
    while(my $line = <$fh>)  {
        chomp($line);
        $line =~ s/[[:punct:]]//gi;
        if(exists $no_punc_name_to_id{$line}) {
            my $id = $no_punc_name_to_id{$line};
            print $line,",","\"$id_to_name{$id}\"",",",$id,"\n";
        }
    }
    

    【讨论】:

    • 这给了我一个好主意,将我的值分配到临时哈希中并修改该值,同时仍返回原始值。 @rozier
    • 一些一般提示,请使用use strict;use warnings;。并使用带有词法文件句柄和正确错误处理的 open 的三个参数版本open my $filehandle , '&lt;' , $filename or die "Cannot read '$filename': $!";
    • 此外,while 可以写成更紧凑的while( my $line = &lt;$fh&gt;) {
    • @rouzier 如果这个哈希是从文件句柄而不是代码中打开的呢?
    • @JDE876 你能说得更具体点吗?这个文件的格式是什么?
    猜你喜欢
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    相关资源
    最近更新 更多