Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
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 (Parson) 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 studying the Monastery: (8)
As of 2015-07-02 06:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (30 votes), past polls