6

ステートメント%detailを使用せずに動的にハッシュを作成したい。evalこのコードはevalステートメントで正常に動作しますが、これを使用せずにこれを実行するより良い方法はあります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$'
        };
4

5 に答える 5

14

関連部分:

if(my @m = /$regex/) {
  for(my $i=0;$i<=$#$array; $i++) {
      $detail{$array->[$i]} = $m[$i];              
  }   
}   
于 2012-08-29T13:23:30.027 に答える
5

for ループを変更します。

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

に:

@detail{@{$array}} = ($_ =~ $regex);
于 2012-08-29T13:30:15.643 に答える
2

最新バージョンの Perl を使用できる場合は(?<name>...)、regexp perlre docsのこの表記を参照してください。$1、$2、$3 などを使用するよりも明確です。

脚本

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);   

出力

$VAR1 = {
          'name'    => 'Vikram',
          'address' => '54, junk, JUNK',
          'age'     => '32',
          'joining' => '2012',
          'salary'  => '12000$'
        };
于 2012-08-29T14:01:52.227 に答える
1

の代わりにとの 2 つの配列@LAST_MATCH_START@LAST_MATCH_END( を参照perldoc perlvar) を一緒に使用できます。に似たものsubstr$1, $2...

$detail{ $array->[$i] } = substr $_, $LAST_MATCH_START[$j], $LAST_MATCH_END[$j] - $LAST_MATCH_START[$j];
于 2012-08-29T13:21:48.597 に答える
1

名前付きキャプチャ グループを使用%matching_hashすると、ハッシュにする必要がなくなります。同時に、数値変数を使用する必要をなくしたり、一致の結果を配列に代入したりします。これは、関連情報を に格納するため%+です。

use 5.10.1;

my @match = (
  qr'^INFO:\s*(?<name>\S+)\s+(?<age>\S+)\s+(?<joining>\S+)',
  qr'^SAL:\s*(?<salary>\S+)',
  qr'ADDRESS:\s*(?<address>.*)',
);

sub get_details{
  my %detail;

  for my $input ( @_ ) {
    for my $match ( @match ){
      next unless $input =~ $match;
      @detail{keys %+} = values %+;
      last;
    }
  }

  return \%detail;
}

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

を 1 つにまとめると、さらに簡単になりますqr

use 5.10.1;

my $match= qr"
    ^INFO:   \s* (?<name>\S+) \s+ (?<age>\S+) \s+ (?<joining>\S+)
  | ^SAL:    \s* (?<salary>\S+)
  | ADDRESS: \s* (?<address>.*)
"x;

sub get_details{
  my %detail;

  for my $input ( @_ ) {
    $input =~ $match;
    @detail{keys %+} = values %+;
  }

  return \%detail;
}

use Data::Dumper;
my @inputs = ( 'INFO: Vikram 32 2012', 'SAL: 12000$','ADDRESS: 54, junk, JUNK' );
say Dumper get_details @inputs
于 2012-08-30T01:41:24.517 に答える