http://qs321.pair.com?node_id=700641

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

hey, I'm trying to split a line of numbers into an array. It seems that the whole line gets transfered to the first element in the array. I want it to seperate into different elements. Here is my code:
$line = " 0 10 9 4 1 0 0 0 2 2 1 1 0"; my @config = split /" "/,$line; $first = $config[0]; print $first;
I'm guessing the way i'm using split may be wrong.

Replies are listed 'Best First'.
Re: split line
by moritz (Cardinal) on Jul 28, 2008 at 21:20 UTC
    If you pass a single blank space to split, it behaves magically and removes all leading spaces:
    use strict; use warnings; use Data::Dumper; my $line = " 0 10 9 4 1 0 0 0 2 2 1 1 0"; my @config = split " ", $line; print Dumper \@config;
Re: split line
by pc88mxer (Vicar) on Jul 28, 2008 at 21:09 UTC
    Try:
    my @config = split / /,$line; # or: my @config = split ' ', $line;
    You were telling perl to split on the string quote-space-quote.
Re: split line
by gaal (Parson) on Jul 28, 2008 at 21:11 UTC
    You're trying to split on a separator that is literally a space between quote marks. Instead, you want to split on any amount of consecutive whitespace:

    my @config = split /\s+/, $line

    Note that you have leading spaces in your string; you may want to strip those out before splitting.

      this works except for the first element, the first element still gets blank. Is there any way to chomp the begining?

        dwm042's answer below does this but there's a shortcut specifically for this kind of thing. Try this:

        my $line = " 0 10 9 4 1 0 0 0 2 2 1 1 0"; my @config = grep /\S/, split / /, $line; # or even my @config = grep /\A\d+\z/, split / /, $line; print join(", ", @config), "\n";

        The second will only pass through numbers (well, positive integers and zero) so something like "6a" will be skipped.

Re: split line
by linuxer (Curate) on Jul 28, 2008 at 21:18 UTC

    you should read the perldoc of split. It can do some magic..., especially when you use $_ as expression; you don't need to bother with leading whitespaces (which might be unwanted in the resulting list)

    my $line = " 0 10 9 4 1 0 0 0 2 2 1 1 0"; my @config = (); { # dedicated block because localizing some variables ($_) local $_ = $line; @config = split; } # some code using @config { # dedicated block because localizing some variables ($, and $\) # show result; local $, = local $\ = $/; print @config; }

    update: code comments added

    update2: see moritz' answer for the better solution whithout localizing $_

Re: split line
by shmem (Chancellor) on Jul 28, 2008 at 21:14 UTC

    You want to split on whitespace, not on quoted whitespace.

    my @config = split / /,$line; # split on single space my @config = split / +/,$line; # split on 1 or more spaces my @config = split /\s+/,$line; # split on one or more of spac +es or tabs

    --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: split line
by dwm042 (Priest) on Jul 28, 2008 at 21:14 UTC
    When you're splitting on any whitespace, you want to use \s+ instead of " ". For example:

    #!/usr/bin/perl -w use strict; my $line = " 0 10 9 4 1 0 0 0 2 2 1 1 0"; my @config = split /\s+/, $line; for (@config) { next unless $_ =~ /\w+/; print $_, "\n"; }
    which has the output:

    C:\Code>perl split_num.pl 0 10 9 4 1 0 0 0 2 2 1 1 0
    Please note that with leading whitespace in $line, the first element returned by split won't contain any text, so you have to trap for that.
      When you're splitting on any whitespace, you want to use \s+ instead of " ".
      except when you want to use " ", which does just what you want, including saving the hassle of the empty first element:
      $ perl #!/usr/bin/perl -w use strict; my $line = " 0\t10\n 9 4 \r 1 0 0 \t0 2 2 1 1 0"; my @config = split " ", $line; for (@config) { print $_, "\n"; } __END__ 0 10 9 4 1 0 0 0 2 2 1 1 0
      thx alot!