in reply to handling erronous input

What i need is for my code to only accept input of 1 digit before the decimal place and 5 after , a space, a comma.. then an 8 character time using : as a seperator that will ignore any data on the same line after the seconds.
You seem to know what you want, so it's just a case of following your spec...
my @data = split /\n/, <<EOS; 1.57163 ,17:29:57 Simple Dealin 1.57163 ,17:29:57 1.57163 ,17:29:57 1.57163 ,17:29:57 1.57163 ,17:29:57 1.57163 ,17:29:57 1.57163 ,17:29:57 1.571 ,17: 1.57172 ,17:30:08 1.57176 ,17:30:10 EOS for ( @data ) { if ( my ( $quote, $time, $comment ) = m{ ^ # start of string (\d\.\d{5}) # a digit, dot and 5 more digits \s, # a space and a comma (\d\d:\d\d:\d\d) # an 8 character time \s* # some spaces (.*) # everything else's a commment $ # end of string }x ) { print "$quote / $time", $comment ne '' ? " / $comment" : '', "\n"; } }

Output:

1.57163 / 17:29:57 / Simple Dealin 1.57163 / 17:29:57 1.57163 / 17:29:57 1.57163 / 17:29:57 1.57163 / 17:29:57 1.57163 / 17:29:57 1.57163 / 17:29:57 1.57172 / 17:30:08 1.57176 / 17:30:10

Update:

See perlre and perlretut for the details

Replies are listed 'Best First'.
Re^2: handling erronous input
by Conal (Beadle) on Apr 06, 2008 at 22:23 UTC
      You've missed part of the regexp out (the bit that captures comments) and missed a backslash out (from \d{5}). It looks like you don't know that, in a regexp, parentheses capture their matches into $1, $2, $3 etc. Again, see perlretut and perlre for the details.

      Your code is similar to mine. You use

      while ( ... ) { unless ( some-condition ) { next } some-code }

      while I prefer the equivalent

      while ( ... ) { if ( some-condition ) { some-code } }

      it's just that (IMHO) yours is harder to read (and longer, too)

      That said, you can use my code with a filehandle like so (I've rearranged it a bit to use unless and made the regexp a more lenient towards spaces)...

      while ( <DATAFILE> ) { chomp; unless ( m{^ (\d\.\d{5}) \s*,\s* (\d\d:\d\d:\d\d) \s* (.*) $ }x ) +{ next } my ( $quote, $time, $comment ) = ( $1, $2, $3 ); # captures my ( $hours, $minutes, $seconds ) = split /:/, $time; #do something with $quote, $hours, $minutes, $seconds & $comment }

        I prefer:

        while ( ... ) { next if some-condition; some-code }

        which not only saves a couple of (trivial I admit) lines of code, it reduces clutter and avoids an extra level of nesting for some-code.


        Perl is environmentally friendly - it saves trees
        gotcha.. i understand completely now.

        thanks again, and its works fine, i just wanted to be certain before i messed anything up.. fwiw here is a link to my project --> http://fxr.freehostia.com/pam/pam_alpha_5.php

        and sorry for my wanton abuse of floating point numbers. ;p

        conal.
      In addition to the problems with your first regex,
      ($hour,$minute,$second) = split(":",$time);) should be
      ($hour,$minute,$second) = split /:/,$time;

      The pattern in split is a regex and needs slashes (or other unambiguous matched punctuation), not quotes. Note also that the last closing paren in your split is "one too many" (and thus, "wrong) and all the parens on the RHS are unnecessary.

      Subject to your taste, note that your extraction to $quote and $timecould be written

      next unless ( $data =~ /^(\d\.\d{5})\s,(\d\d:\d\d:\d\d).*/ ); $quote = $1; $time=$2;

      Update: s/not/note/ in the last narrative paragraph.

        Or

        next unless ( $data =~ /^(\d\.\d{5})\s,(\d{2}:\d{2}:\d{2}).*/ ); $quote = $1; $time=$2;