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

$text = 'a|b|c|||||||||e||||'; @array = split(/\|/,$text); print scalar(@array);
the output is 12...i want the assignment to assign into empty array elements as i would expect...so that the output should be 15. what's going on? how to fix?

Replies are listed 'Best First'.
Re: assigning to array from a split with some empty fields
by hv (Prior) on Apr 14, 2004 at 12:51 UTC

    From the first paragraph of perldoc -f split:

    By default, empty leading fields are preserved, and empty trailing ones are deleted.

    A little further down you'll find that if you specify a negative LIMIT, it is treated as an arbitrarily large LIMIT, so:

    @array = split /\|/, $text, -1;
    should do what you want.

    Hugo

Re: assigning to array from a split with some empty fields
by pelagic (Priest) on Apr 14, 2004 at 12:56 UTC
    split /PATTERN/, EXPR, LIMIT
    If LIMIT is specified and is not negative, the function splits into no more than that many fields (though it may split into fewer if it runs out of delimiters). If LIMIT is negative, it is treated as if an arbitrarily large LIMIT has been specified. If LIMIT is omitted, trailing null fields are stripped from the result (which potential users of pop would do well to remember).

    pelagic
Re: assigning to array from a split with some empty fields
by periapt (Hermit) on Apr 14, 2004 at 13:19 UTC
    Using split without the third argument LIMIT will strip trailing null fields. instead of  @array = split(/\|/,$text) try  @array = split(/\|/,$text,-1). The -1 for LIMIT acts as if an arbitrarily large limit has been specified. The one catch is that the position after the last seperator will be included in the array. In your example, scalar @array = 16 not 15. You could work around this by taking (scalar @array) - 1 or maybe just $#array. Of course, I'm assuming that the seperator is a terminating character on the string and that something like  $text = 'a|b|c|||||||||e||||q'; will not occur. If it might, then scalar @array = 16 is the correct count vice 15
      What I am about to do is stupid (and the long way around), but I just feel like playing around today... so here's a different and more generic way to think about it ... fixing bad input... this should work in scenarios other than just split, call it "thinking outside the box", if you will. Of course, I prefer "there is no box". But there might be a spoon. Or at least a spork. Anyway....
      $text = 'a|b|c|||||||||e||||'; @array = split(/\|/,$text); print join '-', @array;

      can become ...

      $text = 'a|b|c|||||||||e||||'; # our input might have holes in it! $text =~ s#\|\|#\|NULL\|#g; # make holes read as 'NULL' @array = map { $_ eq 'NULL' ? undef : $_ } split(/\|/,$text); print join '-', @array;

      Code is of course untested, but you see the general madness of it. We're filling up a hole with something, digging up the hole, and then getting the hole back just like we left it :) Ok I just like overusing map. If you have a map, everything looks like a nail. Good thing Magellan didn't have a map.

Re: assigning to array from a split with some empty fields
by Tomte (Priest) on Apr 14, 2004 at 13:08 UTC

    from perldoc -f split:

    Empty leading (or trailing) fields are produced when there are positive width matches at the beginning (or end) of the string; a zero-width match at the begin- ning (or end) of the string does not produce an empty field.

    Update:Eeeek, disregard this ugly tip of mine; I should've read further in the mentioned perldoc....

    A possible cure:

    $text = 'a|b|c|||||||||e||||'; @array = split(/\|/,$text . '|MY_END_MARKER'); @array = @array[0..$#array-1]; use Data::Dumper; print Dumper(\@array); print scalar(@array), "\n";
    Note: This produces 16 elements, as the last empty element isn't omitted; just change the -1 into -2 to handle this.

    regards,
    tomte


    An intellectual is someone whose mind watches itself.
    -- Albert Camus