Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Parsing file in Perl post processing

by GotToBTru (Prior)
on Sep 09, 2015 at 13:31 UTC ( [id://1141412]=note: print w/replies, xml ) Need Help??


in reply to Parsing file in Perl post processing

I am thinking there are no embedded spaces in the field names by the otherwise consistent use of underscore. But lines 12 and 13 of the example output do confuse things. Can you clarify?

This almost works (can't get value of last key):

use strict; use warnings; use Data::Dumper; my $string = 'THREAD_ID:1bf1d698 CDR_TYPE:AO SUB_TIME:240815144127 + DEL_TIME:240815144127 OA_ADDR:5.0.OTSDC PRE_TRANS_OA:5.0.OTSDC + DA_ADDR:1.1.966555696176 PRE_TRANS_DA:1.1.966555696176 ORIG_LOC +N:10.100.80.7/7220 ORIG_IDNT:OTS A2P DEST_LOCN:173.209.195 +.44/8341 DEST_IDNT:Syniverse A2P I_ERR:0.0 PPS_ID: PPS_PROFIL +E:AO Submission - OA charged PPS_ERR:1.0 O_ERR:0.0 SILO: + MSG_LEN:22 SEG_NUM:1 of 1 DLV_ATT:0 END_POINT:ESME FINA +L_STATE:DELIVERED REG_DEL:1'; my (@keys) = ($string =~ m/([A-Z_]+):/g); my $z = qr{(?:[A-Z_]+:|$)}; my %hash = map { $_, ($string =~ m/$_:(.+?)\s*$z/)} @keys; print Dumper(\%hash);

Output:

$VAR1 = { 'PPS_ID' => ' ', 'THREAD_ID' => '1bf1d698 ', 'DEST_IDNT' => 'Syniverse A2P ', 'CDR_TYPE' => 'AO ', 'ORIG_LOCN' => '10.100.80.7/7220 ', 'REG_DEL' => '1', 'SILO' => ' ', 'DEST_LOCN' => '173.209.195.44/8341 ', 'O_ERR' => '0.0 ', 'OA_ADDR' => '5.0.OTSDC ', 'PRE_TRANS_DA' => '1.1.966555696176 ', 'PPS_PROFILE' => 'AO Submission - OA charged ', 'I_ERR' => '0.0 ', 'DLV_ATT' => '0 ', 'ORIG_IDNT' => 'OTS A2P ', 'DA_ADDR' => '1.1.966555696176 ', 'MSG_LEN' => '22 ', 'FINAL_STATE' => 'DELIVERED ', 'SEG_NUM' => '1 of 1 ', 'SUB_TIME' => '240815144127 ', 'DEL_TIME' => '240815144127 ', 'PPS_ERR' => '1.0 ', 'END_POINT' => 'ESME ', 'PRE_TRANS_OA' => '5.0.OTSDC ' };

Update: with help of MidLifeXis, corrected regex in map to work even for last key:value pair in list. Update 2: changed final \s in map to \s*. Thanks to NetWallah and poj.

Dum Spiro Spero

Replies are listed 'Best First'.
Re^2: Parsing file in Perl post processing
by NetWallah (Canon) on Sep 09, 2015 at 17:23 UTC
    Great solution (++).

    adding a '+' to the regex eliminates trailing spaces in the values:

    # = my %hash = map { $_, ($string =~ m/$_:(.+?)\s+$z/)} @keys; # =

            Software efficiency halves every 18 months, thus compensating for Moore's Law.

Re^2: Parsing file in Perl post processing
by gbwien (Sexton) on Sep 12, 2015 at 22:51 UTC

    Sorry with my limited exposure to perl I am trying to understand what you are doing in these lines of code

    my $z = qr{(?:[A-Z_]+:|$)}; my %hash = map { $_, ($string =~ m/$_:(.+?)\s*$z/)} @keys

    How does qr work could you please explain what you are doing?

    How is the hash created, I don't understand map and $_, and the $string part

    Thanks Tom

      By using qr{} I am telling Perl the string inside will be used in a regex. See http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators. The most common reason to do this is to save time when you are using the same regex over and over; I use it because it often seems to make sure Perl interprets the regex in the way I expect.

      map {block} @array returns an array created by executing {block} once for each element of @array, each time assigning one value to $_.

      @a=(1,2,3); @a_plus_1 = map { $_ + 1 } @a;

      The block, which in this example is $_ + 1, will be execute 3 times, once for each value in @a. It will put the results also in an array, so the values in @a_plus_1 will be (2,3,4).

      In my solution, I have the map return two values separated by a comma. This is one way to define a hash. You can see this using the debugger:

      perl -d -e 1 Loading DB routines from perl5db.pl version 1.28 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(-e:1): 1 DB<1> %h=(1,2,3,4) DB<2> print $h{1} 2
      Dum Spiro Spero
        Thanks for the explanation, but I am still a bit confused

        about how you exactly created the hash.

        my %hash = map { $_, ($string =~ m/$_:(.+?)\s*$z/)} @keys;

        what I understand is that you use map to create a new list from the @keys array. Am I correct in saying that $_ contains the first entry from @keys array? next part I don't understand at all could you please walk through the code?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1141412]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (2)
As of 2024-04-26 03:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found