分裂和选择列的perl哈希映射/检索问题

时间:2014-04-22 19:07:50

标签: perl hashmap

Perl find and replace multiple(huge) strings in one shot

P.S.这个问题与上述问题的答案有关。

当我尝试替换此代码时:

片段-1

open my $map_fh, '<', 'map.csv' or die $!;
my %replace = map { chomp; split /,/ } <$map_fh>;
close $map_fh;

使用此代码:

片段-2

my %replace = map { chomp; (split /,/)[0,1] } <$map_fh>;

即使密钥存在(如在转储器中),存在语句也不会返回密钥的值。

对于相同的输入文件,它只与单独拆分(Snippet-1)完美配合,而在拆分后选择特定列时不返回任何内容(Snippet-2)。

这里是否发生了一些整数/字符串数据类型混乱?

输入映射文件

483329,Buffalo

483330,Buffalo

483337,Buffalo

脚本输出

$VAR1 = {
          '483329' => 'Buffalo',
          '46546' => 'Chicago_CW',
          '745679' => 'W. Washington',
        };
1 search is ENB 
2 search is 483329 **expected Buffalo here**
3 search is 483330 
4 search is 483337

Perl代码

open my $map_fh, '<', $MarketMapFile or die $!;

if ($MapSelection =~ /eNodeBID/i) {
    my %replace = map { chomp; (split /,/)[0,1] } <$map_fh>;
    use Data::Dumper;
    print Dumper(\%replace);
}
close $map_fh;

my $csv = Text::CSV->new({ binary => 1, auto_diag => 1, eol => $/,quote_space => 0 });
my $tmpCSVFile = $CSVFile."tmp";

open my $in_fh, '<', $CSVFile or die $!;
open my $out_fh, '>', $tmpCSVFile or die $!;
my $cnt=1;

while (my $row = $csv->getline($in_fh)) {
    my $search = $row->[5];
    $search =~ s/[^[:print:]]+//g;
    if ($MapSelection =~ /eNodeBID/i) {
        $search =~ s/(...)-(...)-//g;
        $search =~ s/\(M\)//g;
    }       

    my $match = (exists $replace{$search}) ? $replace{$search} : undef;
    print "\n$cnt search is $search ";
    if (defined($match)) {
        $match =~ s/[^[:print:]]+//g;
        print "and match is $match";
    }

    push @$row, $match;

    #print "  match is $match"; 
    $csv->print($out_fh, $row);
    $cnt++;
}

# untie %replace;
close $in_fh;
close $out_fh;

2 个答案:

答案 0 :(得分:3)

您有范围问题。你的代码:

if ($MapSelection =~ /eNodeBID/i) {
    my %replace = map { chomp; (split /,/)[0,1] } <$map_fh>;
    use Data::Dumper;
    print Dumper(\%replace);
}

%replace块中声明if。将它移到外面,这样以后的代码也可以看到它:

my %replace;
if ($MapSelection =~ /eNodeBID/i) {
    %replace = map { chomp; (split /,/)[0,1] } <$map_fh>;
    use Data::Dumper;
    print Dumper(\%replace);
}

use strictuse warnings放在代码顶部可以帮助您找到这些问题。

此外,您可以使用my $match = $replace{$search},因为它等同于?:操作。

答案 1 :(得分:2)

始终在每个perl脚本的顶部包含use strict;use warnings;。如果您已经这样做并且在声明变量的情况下保持良好的编码实践,那么您将会遇到错误:

Global symbol "%replace" requires explicit package name at

那会让你知道你的代码存在范围问题。避免这种情况的一种方法是在初始化%replace

时使用三元组
my %replace = ($MapSelection =~ /eNodeBID/i)
    ? map { chomp; (split /,/)[0,1] } <$map_fh>
    : ();