Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

CSV File Parsing

by Anonymous Monk
on Feb 28, 2013 at 18:40 UTC ( #1021089=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!
I am parsing a .csv file using "use Text::CSV_XS;". In my code I am trying to only go on with the rest of the process if two columns star with a number, but the code is ignoring the "IF" that checks if the values of $columns[0] and $columns[2] are not numbers. I just can not understand why the "IF" does not work. Here is some of the code to show the issue:
... my $csv = Text::CSV_XS->new(); open (CSV, "<", $file_to_parse) or die "Could not open '$file' $!<b +r>"; while (my $line = <CSV>) { chomp $line; if ($csv->parse($line)) { my @columns = $csv->fields(); #check user file format been uploaded TEST: perl -le 'pr +int "1234567" =~ /^[[:alnum:]]+$/ ? "OK" : "BAD"' if( ($columns[0]!~/^[[:alnum:]]+$/) && ($columns[2]!~/^[ +[:alnum:]]+$/) ) { # wrong format exit; }else{ my $err = $csv->error_input; print "<br><b>Failed to parse line, please call for help +!</b><br>"; } } ...

Thanks for looking!

Comment on CSV File Parsing
Select or Download Code
Re: CSV File Parsing
by blue_cowdawg (Monsignor) on Feb 28, 2013 at 18:57 UTC

    Give us a sample of your data...


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
      Sample Data:
      12345,John Dow, 123456 54321,ANDREW MALL, 8888882 987865,BOGGS BUNNY, 2234566 88777,CLARK KENT R, 888666 112222,DAVOLIO DARK F, 3321777
      Still a problem with:
      if( ($columns[0]!~/^[[:digit:]]+$/) || ($columns[2]!~/^[[:digit:]]+$/) + ) { #stop the program here }
Re: CSV File Parsing
by stephen (Priest) on Feb 28, 2013 at 19:05 UTC

    Your code currently will only throw an error if both columns are non-alphanumeric. If either one contains alphanumeric data, then it won't exit. You might want to change that "&&" to "||".

    stephen

Re: CSV File Parsing
by Not_a_Number (Parson) on Feb 28, 2013 at 19:08 UTC

    POSIX [:alnum:] means alphanumeric You probably want [:digit:].

Re: CSV File Parsing
by Tux (Monsignor) on Feb 28, 2013 at 20:55 UTC
    • Do not use parse (), use getline ()
    • Use a lexical file handle
    • Never use an else branch if the if branch ends the enclosing scope (exit, return, die, last, )
    • Use auto_diag
    • Use positive logic for validation
    # Use auto_diag to see all parsing errors immediately my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1, allow_whit +espace => 1 }); open my $fh, "<", $file_to_parse or die "Could not open '$file' $!"; while (my $row = $csv->getline ($fh)) { # Check first and third field to be numeric only (and not empty) $row->[0] =~ m/^[0-9]+$/ && $row->[2] =~ m/^[0-9]+$/ or exit; # wrong format # THERE CANNOT BE AN ELSE AFTER AN EXIT ! }

    update: your sample data contains spaces. You will have to deal with those, as the current tests will fail for leading and training spaces. Adding allow_whitespace option to the constructor will help you here.


    Enjoy, Have FUN! H.Merijn
Re: CSV File Parsing
by Generoso (Vicar) on Mar 01, 2013 at 02:54 UTC

    Maybe this is what you are taring to do.

    #!/usr/bin/perl # use strict; use warnings; use Text::CSV_XS; my $csv = Text::CSV_XS->new(); #open (CSV, "<", $file_to_parse) or die "Could not open '$file' $!<br> +"; while (my $line = <DATA>) { chomp $line; if ($csv->parse($line)) { my @columns = $csv->fields(); $columns[0] =~ s/ //g; $columns[2] =~ s/ //g; if( ($columns[0]=~/^[0-9]+$/) && ($columns[2]=~/^[0-9]+$/) ) { print "Format ok\n"; foreach (@columns){print $_,"\t";}; print "\n"; }else{ print "Wrong Format\n"; print "First $columns[0] and tird $columns[2] have to be n +umeric\n"; } }else{ my $err = $csv->error_input; print "<br><b>$err Failed to parse line, please call for h +elp!</b><br>" if $err; } } __DATA__ 12345,John Dow, 123456 54321,ANDREW MALL, 8888882 987865,BOGGS BUNNY, 2234566 88777,CLARK KENT R, 888666 126677,CLARK KENT R, xx345778 112222,DAVOLIO DARK F, 3321777

    Results

    perl "E:\perl_TK\perlCSV.pl" Process started >>> Format ok 12345 John Dow 123456 Format ok 54321 ANDREW MALL 8888882 Format ok 987865 BOGGS BUNNY 2234566 Format ok 88777 CLARK KENT R 888666 Wrong Format First 126677 and tird xx345778 have to be numeric Format ok 112222 DAVOLIO DARK F 3321777 <<< Process finished.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1021089]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2014-09-18 22:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (125 votes), past polls