in reply to Re: Re: split/map weirdness: empty strings vs undef
in thread split/map weirdness: empty strings vs undef

You can avoid that behaviour by using a capturing pattern.
$ perl -le'print join " : ", split /(\|)/, "2|3|||||"' 2 : | : 3 : | : : | : : | : : | : : |
This is also documented in perldoc -f split. Of course now every other element is the separator, which isn't what we wanted. So out with them:
$ perl -le'print join " : ", grep ++$i%2, split /(\|)/, "2|3|||||"' 2 : 3 : : : :
There you go.

Update: Yikes! I caught a mistake: the last field still disappears if empty. Count the pipes in the string and the colons in the output.. At this point we lose some grace.. The oneliner is ugly:

$ perl -le'print(join(" : ", grep(++$i%2, split /(\|)/, "2|3|||||"), ( +"")x(1-$i%2)))' 2 : 3 : : : : :
while the multiliner is awkward:
$ perl -le'my @field = grep ++$i%2, split /(\|)/, "2|3|||||"; push @fi +eld, "" unless $i%2; print @field' 2 : 3 : : : : :
Oh well.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re^3: split/map weirdness: empty strings vs undef
by hossman (Prior) on Oct 04, 2002 at 22:34 UTC

    That is damn elegant.

    UPDATE: After reading your update, i was a little dissapointed that i wouldn't be able to use your clean little trick, untill I looked at my data some more. Unlike ever other "seperated" data format I've ever seen, it allways puts a trailing seperator after the last field -- which means your orriginal one liner will work perfect for me ...I need to ignore the last pipe

    go figure

      You know, that gives me another idea for the cases you need to conserve the last field, although it is so similar to the add a bogus field approach that it bears the question whether the capture/grep hoopla is worth the hassle if you went that route anyway: add a field separator to the string.
      $ perl -le'$_ = "2|3|||||"; print join " : ", grep ++$i%2, split /(\|) +/, "$_|"' 2 : 3 : : : : :

      Makeshifts last the longest.