Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically assign hash with $1, $2, $3

Tags:

regex

perl

eval

I want to dynamically create a %detail hash, without using an eval statement. This code is working fine with an eval statement, but is there any better way to perform this without using eval?

my @input=('INFO: Vikram 32 2012','SAL: 12000$','ADDRESS: 54, junk, JUNK');

my %matching_hash= (
                    qr/^INFO:\s*(\S+)\s+(\S+)\s+(\S+)/ =>['name','age','joining'],
                    qr/^SAL:\s*(\S+)/ => ['salary'],
                    qr/ADDRESS:\s*(.*)/ =>['address']
                    );
my %detail;
while(my ($regex, $array) = each(%matching_hash)) {
    foreach (@input){
        if(/$regex/) {
            for(my $i=0;$i<=$#$array; $i++) {
                $j=$i+1;
                eval '$detail{$array->[$i]} = $$j';
            }
        }
    }
}
use Data::Dumper;

print Dumper(\%detail);
++++++++++++++

$VAR1 = {
          'name' => 'Vikram',
          'address' => '54, junk, JUNK',
          'age' => '32',
          'joining' => '2012',
          'salary' => '12000$'
        };
like image 582
user87005 Avatar asked Aug 29 '12 13:08

user87005


3 Answers

Relevant part:

if(my @m = /$regex/) {
  for(my $i=0;$i<=$#$array; $i++) {
      $detail{$array->[$i]} = $m[$i];              
  }   
}   
like image 175
perreal Avatar answered Nov 14 '22 07:11

perreal


Change the for loop:

for(my $i=0;$i<=$#$array; $i++) {
    $j=$i+1;
    eval '$detail{$array->[$i]} = $$j';
}

by:

@detail{@{$array}} = ($_ =~ $regex);
like image 31
Toto Avatar answered Nov 14 '22 09:11

Toto


If you can use lastest version of Perl, see to this notation (?<name>...) in regexp perlre docs It's more clear then using $1, $2, $3 etc.

SCRIPT

use v5.14;
use Data::Dumper;

my @inputs = ( 'INFO: Vikram 32 2012', 'SAL: 12000$','ADDRESS: 54, junk, JUNK' );

my %matching_hash= (
    qr/^INFO:\s*(?<name>\S+)\s+(?<age>\S+)\s+(?<joining>\S+)/ => [ 'name', 'age', 'joining' ],
    qr/^SAL:\s*(?<salary>\S+)/                                => [ 'salary' ],
    qr/ADDRESS:\s*(?<address>.*)/                             => [ 'address' ],
);

my %detail;
while (my ($regex, $array) = each %matching_hash ) {

    INPUT:
    foreach my $input ( @inputs ) {

        next INPUT if not $input =~ m{$regex};

        for my $name ( @$array ) {
            $detail{$name} = $+{$name};
        }
    }
}

say Dumper( \%detail);   

OUTPUT

$VAR1 = {
          'name'    => 'Vikram',
          'address' => '54, junk, JUNK',
          'age'     => '32',
          'joining' => '2012',
          'salary'  => '12000$'
        };
like image 2
Pavel Vlasov Avatar answered Nov 14 '22 07:11

Pavel Vlasov