Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

CSV String Split

by jcleland (Acolyte)
on Nov 17, 2012 at 19:26 UTC ( #1004342=perlquestion: print w/ replies, xml ) Need Help??
jcleland has asked for the wisdom of the Perl Monks concerning the following question:

This doesn't seem all that complicated, but it has me stuck. Well, not stuck, I could write something complicated and accomplish the same task, but I was hoping to be more elegant... and I digress.

I have a CSV file that I need to read and parse fields from. All values are quoted and the quoted string can contain commas. Sometimes, there are missing values in the record (line, row, whatever), these have no quotes at all (so you can have sequential commas for missing fields). Obviously, I need to split these records into fields. Here's an example of what a line might look like:
,"value",,"value1,value2","anothervalue","oh,comeon",,"Givemeabreak"
So trying to use split(',' $_); isn't going to give me what I want. Is there something fancy I can do with a split() regex? Any help is appreciated!

James

Comment on CSV String Split
Download Code
Re: CSV String Split
by afoken (Parson) on Nov 17, 2012 at 19:42 UTC

    The standard answer to problems reading and writing CSV files is Text::CSV_XS. To abuse CSV files as databases, use DBD::CSV, which uses Text::CSV_XS internally.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Thanks! I should have checked cpan first. So installing the package is a problem using
      >$ cpan Text::CSV_XS
      I guess I'll work on that one.
Re: CSV String Split
by Kenosis (Priest) on Nov 17, 2012 at 20:14 UTC

    afoken is correct about using a Module to parse csv data, and your particular data supports that choice, because of the embedded commas within quoted fields. Here's an example using Text::CSV on your data, including a header row--in case you need to handle that (omit, otherwise):

    use strict; use warnings; use Text::CSV; my $csvData = <<END; col0,col1,col2,col3,col4,col5,col6,col7 ,"value",,"value1,value2","anothervalue","oh,comeon",,"Givemeabreak" END my $csv = Text::CSV_XS->new( { binary => 1, auto_diag => 2 } ) or die "Cannot use CSV: " . Text::CSV->error_diag(); # Open the string like a file for reading open my $csvfh, '<', \$csvData or die $!; # Get first line (array reference to parsed column names) my $columnNames = $csv->getline($csvfh); # $row contains an array reference to the parsed csv line while ( my $row = $csv->getline($csvfh) ) { print "Col$_: $row->[$_]\n" for 0 .. 7; } close $csvfh;

    Output:

    Col0: Col1: value Col2: Col3: value1,value2 Col4: anothervalue Col5: oh,comeon Col6: Col7: Givemeabreak

    An array reference to the parsed csv line's data is returned to $row which is later dereferenced using the arrow operator; e.g., $row->[0] contains the value of column zero.

    Hope this helps!

      Unfortunately:
      Checking if your kit is complete... Looks good Bareword found where operator expected at ./Makefile.PL line 1, near " +30 mtime" (Missing operator before mtime?) Number found where operator expected at ./Makefile.PL line 2, near "27 +" (Missing semicolon on previous line?) Bareword found where operator expected at ./Makefile.PL line 2, near " +27 atime" (Missing operator before atime?) Number found where operator expected at ./Makefile.PL line 3, near "30 +" (Missing semicolon on previous line?) Bareword found where operator expected at ./Makefile.PL line 3, near " +30 ctime" (Missing operator before ctime?) ERROR from evaluation of /usr/share/cpan/build/HMBRAND-iipV8I/Text-CSV +_XS-0.92/M akefile.PL: ERROR from evaluation of /usr/share/cpan/build/HMBRAND-iip +V8I/Text-C SV_XS-0.92/PaxHeaders.23664/Makefile.PL: syntax error at ./Makefile.PL + line 1, n ear "30 mtime"

      Not sure what to make of that, but the module doesn't want to install. tried cpan <module> and manual build as well. Puke.
        NM, missing modules. Fixed. Thanks for the help and examples guys!

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2014-09-21 17:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

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











    Results (173 votes), past polls