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

I have the following string:
my $str = "123**abc******";
I want to use '**' as the delimiter. Here is my code to split this string:
my @values = split(/\*\*/,$str); warn Dumper(\@values);
Which gives me the following:
$VAR1 = [ '123', 'abc' ];
What I need it to return is this (so that the two trailing '**' are also split, but it just gives an empty value):
$VAR1 = [ '123', 'abc', '', '' ];
Is this possible to do with split?

Replies are listed 'Best First'.
Re: Split a string with multiple trailing delimeters?
by kennethk (Abbot) on Jan 04, 2011 at 18:45 UTC
    As documented in split:
    If LIMIT is specified and positive, it represents the maximum number of fields the EXPR will be split into, though the actual number of fields returned depends on the number of times PATTERN matches within EXPR. If LIMIT is unspecified or zero, trailing null fields are stripped (which potential users of pop would do well to remember). If LIMIT is negative, it is treated as if an arbitrarily large LIMIT had been specified. Note that splitting an EXPR that evaluates to the empty string always returns the empty list, regardless of the LIMIT specified.

    So my @values = split(/\*\*/,$str,-1); returns:

    $VAR1 = [ '123', 'abc', '', '', '' ];

    Note you have a trailing entry, hence 3 empty strings not 2.

      Ah, thank you. -1 is a lot cleaner than an arbitrarily large value.
Re: Split a string with multiple trailing delimeters?
by BrowserUk (Patriarch) on Jan 04, 2011 at 18:41 UTC

    If you use the third split parameter it will do the trick. A value of 5 works for your example, but any value larger also works which is useful if you are not sure how many fields there are:

    print "'$_'" for split '[*]{2}', $s, 100;; '123' 'abc' '' '' ''

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Actually a negative limit works as an infinitely large value and you don't have to worry about that one edge case n years down the road that surpasses what you've chosen that usually is large enough.</nit>

      Quoth the docs for split:

      If LIMIT is negative, it is treated as if an arbitrarily large LIMIT had been specified.

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

      Using the third parameter worked. Thank you very much!
Re: Split a string with multiple trailing delimeters?
by ikegami (Patriarch) on Jan 04, 2011 at 19:04 UTC

    Given your desired output, '**' is a terminator rather than a separator, so split isn't appropriate.

    my @values = $str =~ /(.*?)\*\*/sg;

    If the last terminator is optional:

    my @values = $str =~ /(.*?\*\*|.+)/sg; s/\*\*\z// for @values;
Re: Split a string with multiple trailing delimeters?
by logix (Initiate) on Jan 04, 2011 at 19:19 UTC
    Try this
    my @values = split(/\*\*/,$str,-1);
    In perldoc on split, it says:

    "Empty trailing fields, on the other hand, are produced when there is a match at the end of the string (and when LIMIT is given and is not 0)"

    From http://perldoc.perl.org/functions/split.html
Re: Split a string with multiple trailing delimeters?
by mikeraz (Friar) on Jan 04, 2011 at 19:34 UTC

    If you know in advance how many fields to expect you can specify the limit parameter to sort.

    If you don't you can determine the number with something like

    my $tstr = $str; my $count = $tstr =~ s/\*\*//g;
    and $count will have your limit.

    Be Appropriate && Follow Your Curiosity