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

i have an array with one line per element. like this element # content 1 ***1*** 2 stuff 3 stuff 4 ***end1*** 5 ***2*** 6 stuff 7 stuff 8 ***end2*** and i want el. 1 to hold the strings between ***1*** and ***end1*** an +d so on how should i do this?

Replies are listed 'Best First'.
(Ovid - the lone range operator to the rescue!) Re: sorting an array
by Ovid (Cardinal) on Aug 21, 2001 at 00:45 UTC

    I'm just guessing as to your intention, but if you mean that each element will hold an array ref of middle elements, try the following:

    use strict; my @array = qw/ ***1*** first second ***end1*** ***2*** third fourth * +**end2*** /; my @new_array; foreach my $element ( @array ) { my $mark = quotemeta "***"; my $where = ( $element =~ /$mark(\d+)$mark/ .. $element =~ /${mark +}end$1+$mark/ ); push @{$new_array[ $1 - 1 ]}, $element if $where != 1 and $where ! +~ /E/ ; } use Data::Dumper; print Dumper \@new_array;

    Output from above snippet:

    $VAR1 = [ [ 'first', 'second' ], [ 'third', 'fourth' ] ];

    If you want the array elements to hold a concatenated string, change the push to a concatenation.

    Cheers,
    Ovid

    Vote for paco!

    Update: Fixed stupid little useless loop that chipmunk alerted me to :)

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: sorting an array
by Cine (Friar) on Aug 21, 2001 at 00:15 UTC
    If I understand you correctly:
    my @temp; my @newarray; foreach(@array) { next if (/^\*+\d+\*+$/); if (/^\*+end\d+\*+$/) { push @newarray,join"",@temp; @temp = (); next; } push @temp,$_; } push @newarray,join"",@temp if (@temp); @array=@newarray;


    T I M T O W T D I
Re: sorting an array
by George_Sherston (Vicar) on Aug 21, 2001 at 01:16 UTC
    This'll do it with two lines and a sideways leap:
    my $array = join(",",@array); my @newarray = ($array =~ /\*\*\*\d+\*\*\*,(.*?),\*\*\*end\d+\*\*\*/g);
    (I know that's three lines, but that's the way the monk wraps) (shd that be raps?)

    If you want the delimiters, ***1*** etc, to be part of the new elements, then leave the ()s out of the regex. Enjoy!, as they say.

    § George Sherston
Re: sorting an array
by runrig (Abbot) on Aug 21, 2001 at 00:43 UTC
    Another way:
    my @hold; for (@array) { if (my $status = /^\*{3}1\*{3}$/../^\*{3}end1\*{3}$/) { next if $status == 1 or $status =~ /E0/; push @hold, $_; } }
    Update: Typo. Fixed. l=>1. Like I can read let alone tell the difference with that small of a font :-)

      Almost, but not quite :) Here's your output:

      $VAR1 = [ 'first', 'second', '***end1***', '***2***', 'third', 'fourth', '***end2***' ];
      </code>

      Cheers,
      Ovid

      Vote for paco!

      Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: sorting an array
by maddfisherman (Sexton) on Aug 21, 2001 at 01:15 UTC
    sorry for the confusion what im trying to do is this
    @array = (***1***, stuff1, stuff1b, ***end1***, ***2***, stuff 2, stuf +f2b, ***end2*** ...)
    I want that to go to
    @newarray = (stuff1stuff1b, stuff2stuff2b)
    hope that clears it up a bit thanks