my $w= "\s\0"; # Whitespace my $s= "\x14\0"; # Separator my $q= "\xFE\0"; # Quote / escape my $c= ".."; # Character # Versions we can apply modifiers to: my $W= "(?:$w)"; my $S= "(?:$s)"; my $Q= "(?:$q)"; my $C= "(?:$c)"; $/= "\r\0\n\0"; while( ) { my @row; my $end= 'none'; while( m{ \G # Don't skip any characters $W*(?!$w) # Ignore whitespace outside quotes (?: # Either quoted value of bare value: $q( # Opening quote, keep quoted value as $1 (?: $q$q # An escaped quote | (?!$q)$c # Or a non-quote )* # Zero or more characters per value )$q(?!$q) # Closing quote (not escaped) | ( # Capture the bare value as $2 (?: (?!$s|$q)$c # A non-separator, non-quote character )+ # One or more 'bare' characters )(?