in reply to better way to convert a string into an array and an hash

use strict; use warnings; my $string = "1:1,2:1,3:2,500:2,505:1"; my (@array, %hash); $string =~ s/(\d+):(\d+)(?:,|$)/$hash{$1}=$2;push(@array, $1)/ge; use Data::Dumper; print Dumper(\@array, \%hash);
the e on the end of the s// tells perl to execute what's on the right hand side and the g tells it to match the left hand side as many times as possible. So you effectively end up with the code on the right in a loop over all the things that match the pattern.

The (?:,|$) makes sure that the pair of number si followed by a , or that we're at the end of the string.

One thing to note is that this will destroy the contents of $string.

Replies are listed 'Best First'.
Re^2: better way to convert a string into an array and an hash
by ikegami (Patriarch) on Oct 05, 2004 at 18:44 UTC

    May I recommend

    while ($string =~ /(\d+):(\d+)(?:,|$)/g) { $hash{$1} = $2; push(@array, $1); }

    over

    $string =~ s/(\d+):(\d+)(?:,|$)/$hash{$1}=$2;push(@array, $1)/ge;
Re^2: better way to convert a string into an array and an hash
by ambrus (Abbot) on Oct 05, 2004 at 18:45 UTC

    You are using s///ge only for the side effects of the code in the substitution part. Why do you need a substitution then? You could just as well say

    use warnings; use strict; my $string = "1:1,2:1,3:2,500:2,505:1"; my (@array, %hash); while ($string =~ /(\d+):(\d+)(?:,|$)/g) { $hash{$1}=$2;push(@array, $1) }; use Data::Dumper; print Dumper(\@array, \%hash);

      Simply because it gives you a free loop. I first saw this idiom about 10 years ago for decoding a cgi params into a hash. Something like

      $p =~ s/(.*?)=(.*?)(&|$)/$v=$2;$v=~s/%(..)/chr(hex($1))/ge;$p{$1}=$v/g +e
      a substitution within a substiution!

      I also thought it might be quicker but after a quick benchmark it seems not.

      I suppose I could have used

      [/(\d+):(\d+)(?:,|$)(?{$hash{$1}=$2;push(@array, $1);1})/g];
      for a free loop without destroying the string but isn't much faster.