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

Hi All,
  I'm reading data from a pipe delimited file. I want to split this data into 5 variables, although there may be more than 4 pipes per line, so I want the last variable to contain all that's left (including the remaining pipes). I'm wondering what the clever way to do it is. My current code looks like:-
my @data = split(/\|/, $line); my $var1 = unshift @line; my $var2 ... my $var5 = join @line;
To me this seems a bit long winded. I'm sure one of you guys can show me a better way to do it :)

Thanks in advance

Lyle

Replies are listed 'Best First'.
Re: split and join, what's the clever way to do it
by ikegami (Patriarch) on Jan 27, 2008 at 03:49 UTC

    It's already been specified that specifying split's 3rd argument is the solution.

    I just wanted to note the 3rd argument is also very useful to disable split's default of removing trailing blank fields.

    >perl -le"print join '|', split /\|/, '|a|b|c||'" |a|b|c >perl -le"print join '|', split /\|/, '|a|b|c||', -1" |a|b|c||

    I've always wondered why split is lossy by default, especially since I rarely if ever need the lossy behaviour. Either I don't care since I shouldn't be getting blank fields, or I want to keep the blank fields.

      And there was me thinking that the 3rd argument would mean ignoring any extra pipes.

      Thanks for all the info guys!

      Lyle
Re: split and join, what's the clever way to do it
by hipowls (Curate) on Jan 27, 2008 at 03:35 UTC
    my ($var1, $var2, $var3, $var4, $var5) = split /\|/, $line, 5;
    See split

    Update: Changed split to use /\|/ instead of '|'. Thanks for pointing it out.

      You've introduced a bug. The first arg of split is a regex even if you obfuscate that fact by using quotes, so the | needs to be escaped:

      split '|', $line, 5; # WRONG split '\\|', $line, 5; # ok split /\|/', $line, 5; # Better split qr/\|/', $line, 5; # Can also use qr// split $re, $line, 5; # or compiled regexes

      Other useful syntaxes:

      my @rec = = split /\|/, $line, 5;
      my %rec; @rec{qw( var1 var2 var3 var4 var5 )} = split /\|/, $line, 5;
        Having been bitten by that myself, are there any documents explaining why split behaves this way rather than the (IMO more sensible) alternative of splitting on a regex if it's /specified as a regex/ and splitting on a plain string if it's 'specified as a plain string'?

      The first argument to split is a regex, not a string. It makes a difference.

      $ perl -le '$line = "a|b|c|d"; print "-- $_:\n", join( "\n", split( $_ +, $line ) ) for ( qr/\|/, "|" )' -- (?-xism:\|): a b c d -- |: a | b | c | d

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

Re: split and join, what's the clever way to do it
by pilcrow (Sexton) on Jan 30, 2008 at 18:20 UTC
    my @data = split(/\|/, $line); my $var1 = unshift @line; my $var2 ... my $var5 = join @line;

    As an aside, surely my $var1 = shift @data was meant above.

    -Mike