use strict; use warnings; use Data::Dumper; my $text=""; while () { $text.=$_; my @new; pos($text)=0; my $last=0; while ($text=~m{ \G (?: "((?:[^"]+|"")*)" # quoted section | ([^",]+) # unquoted | ((?=\s*,)) ) (?:\s*,\s*|\s*\z) }gmx) { push (@new, $+); $last=$+[0]; $new[-1]=~s/""/"/g; } if ($last==length($text)) { push (@new, "") if $text=~/,$/; print "Rec:".Data::Dumper->new([\@new])->Terse(1) ->Useqq(1)->Indent(0)->Dump()."\n"; $text=""; } } print "Error: $text\n" if $text; __DATA__ 1,the,simple,"case " "with","quoted" , "strings that contain spaces" "with","quoted" , "comma, internally" "with","quoted" , "comma, internally, with ""null"" data",,, """"""""