awohld has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to extract certain lines out of some text:

employee[1] = new employee_element(15,"Bob","Smith","Sales");\n

And pop them into an array of arrays of that include the employee info and the index of "employee[x]" that it was found with in the text block. I know to use $1 and $2 to get the matching text but I don't know how to use "map" to get it.

The above line text would become an array that looks like:
[ 1, 15,"Bob","Smith","Sales" ]

Below is my try at making it work but I can't figure it out.
#!/usr/bin/perl -w use strict; use Data::Dumper; my $data = qq( Stuff here junk text <tr><td class='menutext' align='center'><input typ employee[1] = new employee_element(15,"Bob","Smith","Human Resources") +; employee[2] = new employee_element(03,"Harry","Jones","Coordinato"); employee[3] = new employee_element(23,"Janet","Davies","Development"); employee[4] = new employee_element(95,"James","McAvery","Communication +s"); more junk text ); # Question: How do I transform the above chunk of text into what I w +ant? # I need to get out the employee_element info and put it # into an array of arrays as seen below. The employee[x] identifier # needs to also be the first part of the array. I know to use # $1 for the match, but I don't know how to apply it to this. # Here is my attempt to map out the employees info into an array my @employees_my_try; push @employees_my_try, ( map { $_ =~ m/^employee\[(.*)\] = new employee_element\((.*)\);$/g } split "\n", $data ); print Dumper \@employees_my_try; # End result, store each employee info into an array of arrays with # employees index also listed. my @employees = [ [ 1, 15,"Bob","Smith","Human Resources" ], [ 2, 03,"Harry","Jones","Coordinato" ], [ 3, 23,"Janet","Davies","Development" ], [ 4, 95,"James","McAvery","Communications" ] ]; print Dumper @employees;

Replies are listed 'Best First'.
Re: Parsing and Matching Text with Map
by Fletch (Bishop) on Oct 05, 2006 at 18:47 UTC

    You're close.

    push @employees_my_try, ( map { if( my($idx, $rest) = $_ =~ m/^employee\[(.*?)\] = new employee_ +element\((.*)\);$/ ) { my @split = map { s/\A"(.*)"\z/$1/; $_ } split( /,/, $rest ); [ $idx, @split ] } else { () } } split "\n", $data ); print Dumper \@employees_my_try;
      Okay, now I made a little change. I'm storing the data in a hash and the key is the index.
      # Create hash with employee index as key. my %employees = ( map { $_ =~ m/^employee\[(.*?)\] = new employee_element\((.*)\);/g } split "\n", $data );
      Right now the "value" is a string. How can I get it to change to an array inside this map expression?

      I can alter it outside the function using this:
      $employees{$_} = \[split ",", $employees{$_} ] foreach keys %employees;
        You process as advised, and at the end of the map block you return a key/value pair:
        map { ... $index, [ @list ]; }

        That will be fine to construct a hash.

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Parsing and Matching Text with Map
by jwkrahn (Abbot) on Oct 05, 2006 at 21:47 UTC
    $ perl -e' use Data::Dumper; my $data = qq( Stuff here junk text <tr><td class=\047menutext\047 align=\047center\047><input typ employee[1] = new employee_element(15,"Bob","Smith","Human Resources") +; employee[2] = new employee_element(03,"Harry","Jones","Coordinato"); employee[3] = new employee_element(23,"Janet","Davies","Development"); employee[4] = new employee_element(95,"James","McAvery","Communication +s"); more junk text ); my @employees_my_try = map { /^employee\[(\d+)] = new employee_element\((\d+),"([^"]+)","([^"]+ +)","([^"]+)"\);/ ? [ $1, $2, $3, $4, $5 ] : () } split /\n/, $data; print Dumper \@employees_my_try; ' $VAR1 = [ [ '1', '15', 'Bob', 'Smith', 'Human Resources' ], [ '2', '03', 'Harry', 'Jones', 'Coordinato' ], [ '3', '23', 'Janet', 'Davies', 'Development' ], [ '4', '95', 'James', 'McAvery', 'Communications' ] ];
Re: Parsing and Matching Text with Map
by shmem (Chancellor) on Oct 05, 2006 at 19:51 UTC
    What do you get if you
    print Dumper \@employees_my_try;

    ? You where close, but at the end of the map block you return only whether the match was successful. A bit more munging and stuffing the captured values into an anonymous array will do:

    map { $_ =~ m/^employee\[(.*)\] = new employee_element\((.*)\);$/g; my ($index, $text) = ($1, $2); my @list = split/,\s*/, $text; s/"//g for @list; [ $index, @list ]; } split "\n", $data

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}