use strict;
use warnings;

# so ziemlich alles, was mir einfaellt
my $test1 = q/,   "Leerzeichen  ",,,   eins zwei , drei,, 'Kuchen, / 
          . q/""mit"" Streussel' , und, "ein, \"x"  , y , /;

# typische CSV-Zeile
my $test2 = q/SAR001,"","Nevermind, Inc.","John Doe","SZVAB",/
          . q/N,8,1,0,7,"Error, Brain Dumped"/;

# desgleichen mit Leerzeichen
my $test3 = q/SAR001, "", "Nevermind, Inc.", "John Doe", "SZVAB",/
          . q/N, 8 ,1,0    ,7, "Error, Brain Dumped"/;

# ziemlich leere Zeile
my $test4 = q/,/;

my @result = split_string($test1);
print $test1, "\n";
print join('|', @result), "\n\n";

@result = split_string($test2);
print $test2, "\n";
print join('|', @result), "\n\n";

@result = split_string($test3);
print $test3, "\n";
print join('|', @result), "\n\n";

@result = split_string($test4);
print $test4, "\n";
print join('|', @result), "\n\n";


sub split_string
  {
  my $text = shift;
  my @new = ();
  push(@new, $+) while $text =~ m{ \s*(
        # gruppiert Felder innerhalb von Anfuehrungszeichen
        "([^\"\\]*(?:\\.[^\"\\]*)*)"\s*,?
        # gruppiert Felder innerhalb von Apostrophen
        | '([^\'\\]*(?:\\.[^\'\\]*)*)'\s*,?
        # entfernt fuehrende/folgende Leerzeichen
        | ([^,\s]+(?:\s+[^,\s]+)*)\s*,?
        # leere Felder
        | (),
        )\s*}gx;
  # leeres Feld am Ende
  push(@new, '') if $text =~ m/,\s*$/;
  # Array zurueckgeben
  return (@new);
  }
