Micheal_Sam
Micheal_Sam

Reputation: 109

Perl grepping similar words

I have below output in some variable in my perl script-the out output is actually coming from some executable which I am storing in variable $retval in this case- example below

my $retval=`imp_vol -u 110.5 -s 110.9 -p 0.005 -t 0.041 -c 1`                                                                                                               

Black Scholes NVol = 1.19711
Black Scholes NDelta = 0.0494522
Black Scholes NGamma = 0.42176
Black Scholes NTheta = -0.302207
Black Scholes NVega = 0.0207006
Black Scholes Vol = 0.0108141
Black Scholes Delta = 0.049565
Black Scholes Gamma = 0.42329
Black Scholes Theta = -0.302212
Black Scholes Vega = 2.29159

Here imp_vol is my executable with different parameters..and it prints different BLack Scholes values.Now My purpose is to get all the Black Scholes Values-Below is what I am using currently using in perl script-

if($retval=~/\s*Black\s+Scholes\s+Vol\s*\=\s*(.*)/i){
       $vol=$1;
    }
    if($retval=~/\s*Black\s+Scholes\s+Delta\s*\=\s*(.*)/i){
       $delta=$1;
    }
    if($retval=~/\s*Black\s+Scholes\s+Gamma\s*\=\s*(.*)/i){
       $gamma=$1;
    }
    if($retval=~/\s*Black\s+Scholes\s+Theta\s*\=\s*(.*)/i){
       $theta=$1;
    }
    if($retval=~/\s*Black\s+Scholes\s+Vega\s*\=\s*(.*)/i){
       $vega=$1;
    }
    if($retval=~/\s*Black\s+Scholes\s+NVol\s*\=\s*(.*)/i){
       $nvol=$1;
    }
    if($retval=~/\s*Black\s+Scholes\s+NDelta\s*\=\s*(.*)/i){
       $ndelta=$1;
    }
    if($retval=~/\s*Black\s+Scholes\s+NGamma\s*\=\s*(.*)/i){
       $ngamma=$1;
    }
    if($retval=~/\s*Black\s+Scholes\s+NTheta\s*\=\s*(.*)/i){
       $ntheta=$1;
    }
    if($retval=~/\s*Black\s+Scholes\s+NVega\s*\=\s*(.*)/i){
       $nvega=$1;
    }

Any help will be applauded

Upvotes: 4

Views: 136

Answers (2)

Borodin
Borodin

Reputation: 126722

First of all you should put the text returned by the backticks imp_val ... into an array instead of a scalar. That will split it into lines and make it much easier to handle.

Then you can process it into a hash using just map with a regular expression. It looks like this. Note that I have used Data::Dump and dd only to demonstrate the resulting hash structure: you would not need it in your own code

use strict;
use warnings;

use Data::Dump;

my @retval  = `imp_vol -u 110.5 -s 110.9 -p 0.005 -t 0.041 -c 1`;
my %scholes = map { /(\w+)\s*=\s*(-?[\d.]+)/ } @retval;

dd \%scholes;

output given the data you show in your question

{
  Delta  => 0.049565,
  Gamma  => 0.42329,
  NDelta => 0.0494522,
  NGamma => 0.42176,
  NTheta => -0.302207,
  NVega  => 0.0207006,
  NVol   => 1.19711,
  Theta  => -0.302212,
  Vega   => 2.29159,
  Vol    => 0.0108141,
}

Update

From your other comments it looks like you want a subroutine to return a specific sequence of values. I suggest that this code would be best:

use strict;
use warnings;

use Data::Dump;

sub scholes {
  my @retval=`imp_vol -u 110.5 -s 110.9 -p 0.005 -t 0.041 -c 1`;
  my %scholes = map { /(\w+)\s*=\s*(-?[\d.]+)/ } @retval;
  return @scholes{qw/ Vol Delta Gamma Theta Vega NVol NDelta NGamma NTheta NVega /};
}

dd [ scholes ];

output

[
  0.0108141,
  0.049565,
  0.42329,
  -0.302212,
  2.29159,
  1.19711,
  -0.302207,
  0.0207006,
  0.0494522,
  0.42176,
]

Upvotes: 1

perreal
perreal

Reputation: 97948

You can instead collect them in a hash:

use strict;
use warnings;

my $retval = <<HERE;
Black Scholes NVol = 1.19711
Black Scholes NDelta = 0.0494522
Black Scholes NGamma = 0.42176
Black Scholes NTheta = -0.302207
Black Scholes NVega = 0.0207006
Black Scholes Vol = 0.0108141
Black Scholes Delta = 0.049565
Black Scholes Gamma = 0.42329
Black Scholes Theta = -0.302212
Black Scholes Vega = 2.29159
HERE

my %h; 
while ($retval =~ /Black\s+Scholes\s+(\S*)\s*\=\s*(\S*)/ig) {
    $h{lc $1} = $2; 
}

for my $k (keys %h) {
    print "$k, $h{$k}\n";
}

Produces:

ntheta, -0.302207
nvega, 0.0207006
ndelta, 0.0494522
vol, 0.0108141
theta, -0.302212
ngamma, 0.42176
nvol, 1.19711
vega, 2.29159
delta, 0.049565
gamma, 0.42329

Upvotes: 4

Related Questions