Well, if you don't want to use a module, you could try something like the following code - it basically breaks the job down into several parts. The only major requirement is that all your quotes should be valid pairs (you should probably add a test to check that you have an even number of quotes and that you have the number of fields per line that you expect).
- Pull out the quoted sections
- Replace ',' with '_comma_' in the quoted sections
- Restore the quoted sections back into position
- Safely split on ',' (since quoted commas are now '_comma_')
- Replace '_comma_' with ','
Here's the code:
use strict; my @output; while(<DATA>){ chomp; next unless $_ =~ /\S/; # push any quoted stuff (incl. quotes) onto array... (we assume that + all quotes are paired) push my @quoted, ($_ =~ /"([^"]*)"/g); # replace any commas in the array with '_comma_' foreach my $quote(@quoted){ $quote =~ s/,/_comma_/g; } # now replace the ',' versions with the "_comma_" versions $_ =~ s/"[^"]*"/'"' . (shift @quoted) . '"'/ge; # now we can safely split on any commas (quoted commas are now '_com +ma') push @output, [split /,/]; # finally, replace any '_comma_' values with ',' in the latest eleme +nt of output foreach(@{$output[$#output]}){ s/_comma_/,/g; } } # what have we got? foreach(@output){ foreach(@{$_}){ print "$_:"; } print "\n"; } __DATA__ 123,456,"hello, world, goodbye, world",789 123,456,"hello, world, goodbye, world",789,"foo, bar","bar, foo" "hello, world","goodbye, world",123,"foo" "hello" 123,456,"goodbye, world",789
Tom Melly, pm@tomandlu.co.ukmap{$a=1-$_/10;map{$d=$a;$e=$b=$_/20-2;map{($d,$e)=(2*$d*$e+$a,$e**2 -$d**2+$b);$c=$d**2+$e**2>4?$d=8:_}1..50;print$c}0..59;print$/}0..20
|
---|
In Section
Seekers of Perl Wisdom