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

Hi all, I have a file looking similar to:
123.45 345.3 234.67 34.56 234.1 123.87
I have used split by whitespace successfully, however, i have a some lines
897.34 567.32-100.90
in this instance how can i make the split multifunctional to recognise the third column when a negative is introduced. Basically split into three distinct columns? Thanks

Retitled by davido from 'split'.

Replies are listed 'Best First'.
Re: Split on whitespace or other criteria
by bgreenlee (Friar) on Jan 30, 2005 at 20:33 UTC
    This will work for your example:
    my @cols = split /\s+|(?<=\d)(?=\-)/;
    It splits on whitespace or on a boundry where there's a digit followed by a dash.

    -b

Re: Split on whitespace or other criteria
by Tanktalus (Canon) on Jan 30, 2005 at 21:03 UTC

    That doesn't look like a split file ... it looks like a substr file. And, of course, the best way to get fields from a fixed-width line is ... unpack.

    while(<DATA>) { my @fields = unpack "A7A6A*", $_; print join(':', map { sprintf "%.2f", $_ } @fields), "\n"; } __DATA__ 123.45 345.3 234.67 34.56 234.1 123.87 897.34 567.32-100.90
    Of course, such a small sample of your data doesn't lend itself to perfect analysis, so the regexp's may be more suiting.

Re: Split on whitespace or other criteria
by neniro (Priest) on Jan 30, 2005 at 20:38 UTC
    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; while(<DATA>) { chomp; s/-/ -/g; print Dumper [split(/\s+/, $_)]; } __DATA__ 123.45 345.3 234.67 34.56 234.1 123.87 897.34 567.32-100.90
    How about adding a blank before the '-'sign.
      yes, should hav mention that a blank is required before -ve sign thanks
        @array = grep { $_ !~ /^\s*$/ } split '(\d+(?:\.\d*)*)+|\D+', $line;

        So there is no matter what chars you put between digits.
Re: Split on whitespace or other criteria
by Roy Johnson (Monsignor) on Jan 30, 2005 at 21:05 UTC
    split /\s+|(?=-)/
    This works (somewhat surprisingly) even in the case where there is a space before the minus. That is because split will not split a string in the same place twice (to avoid infinitely returning empty fields).

    Caution: Contents may have been coded under pressure.
Re: Split on whitespace or other criteria
by borisz (Canon) on Jan 30, 2005 at 21:09 UTC
    Propaby m// is even usable for you. I suppose a line is in $_.
    my @values = /\d+\.\d+/g;
    Boris
Re: Split on whitespace or other criteria
by dimar (Curate) on Jan 30, 2005 at 21:17 UTC

    Just curious ... why do people seem to use

    /(?=\-)/
    ... in regex, instead of ...
    /[\-]/

    Is the latter variant inferior? going out of style?

      The former is a lookahead; it does not eat a character. The latter consumes the "-". Oh, there's no need to backslash it.

      Caution: Contents may have been coded under pressure.
Re: Split on whitespace or other criteria
by Anonymous Monk on Jan 30, 2005 at 21:26 UTC
    the split methods all work, however, how can i insert a whitespace before the negative value when putting into an array?
    123.45 65.78-100.98 becoms 123.45 65.78 -100.98
    thanks for your help people

      neniro already gave you a solution for that. Are you still having problems?

      -- vek --