in reply to Easy Split

Text::CSV/Text::CSV_XS would do the trick as well.
my $csv = Text::CSV_XS->new ({ binary => 1, sep_char => ':' }); while (my $row = $csv->getline(*ARGV)) { my @fields = @$row; ... } die($csv->error_diag, "\n") if !$csv->eof;

Replies are listed 'Best First'.
Re^2: Easy Split
by ropey (Hermit) on Jul 03, 2009 at 15:48 UTC
    ok - so does that mean there is no solution just with split?
      Hi ropey,

      If I'm understanding your requirements correctly, you could use a negative-lookbehind assertion like this:

      use strict; use warnings; my $string = '111111111:22222\:2222:333333333:4444444'; my @split = split(/(?<!\\):/, $string); print "Results:\n"; map { print "$_\n" } @split;

      Which produces this:

      Results: 111111111 22222\:2222 333333333 4444444
      You'd still need to handle the escaped '\', but the above code at least doesn't split on ':' if it's preceded by '\'.  Of course, that doesn't take into account the situation where a backslash '\' is really the second of a pair of backslashes, as in:
      my $string = 'AAA:BBB:CCC\\:CCC:DDD";

      ... so it's really only a simplistic, partial solution.


      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      It means that $csv->getline is much simpler, much more readable and much more maintainable than any solution involving split, so I didn't see the point of coming up with a solution involving split.
      split /[^\\](?:\\\\)*\K:/, $string worked Ok for me: it splits on an even number of inverted bars, followed by a colon, but keeps the bars in the split strings.
      sub x($) { local($_) = @_; say "\n$_ ==>"; say for split /[^\\](?:\\\\)*\K:/, $_ } x $_ for <DATA>; __DATA__ 111111111:22222\:2222:333333333:4444444 111111111:22222\\:2222:333333333:4444444 111111111:22222\\\:2222:333333333:4444444 111111111:22222\\\\:2222:333333333:4444444
      Result:
      111111111:22222\:2222:333333333:4444444 ==> 111111111 22222\:2222 333333333 4444444 111111111:22222\\:2222:333333333:4444444 ==> 111111111 22222\\ 2222 333333333 4444444 111111111:22222\\\:2222:333333333:4444444 ==> 111111111 22222\\\:2222 333333333 4444444 111111111:22222\\\\:2222:333333333:4444444 ==> 111111111 22222\\\\ 2222 333333333 4444444
      Beware that '222\\:222' only has ONE inverted bar... :-D
      []s, HTH, Massa (κς,πμ,πλ)