in reply to Using a regex to replace looping and splitting

You could do a single split on either a '|' or a ':' then process the resulting stream two items (key and value) at a time filtering out the 'special' pairs. You could use the core List::Util->pairs() if on 5.20 or later, or List::MoreUtils->natatime() from CPAN if not, to process in pairs. I use groupsOf() which I wrote when when working in a restricted environment with early Perl versions and no chance of installing non-core modules.

use strict; use warnings; use Data::Dumper; sub groupsOf (&$@); my $dbStr = q{special:1001:area_code:617|special:1001:zip_code:02205|special:10 +01:dow:0|special:1001:tod:14}; my $rhRes = { groupsOf { $_[ 0 ] eq q{special} ? () : @_ } 2, split m{\||:}, $dbS +tr }; print Data::Dumper->Dumpxs( [ $rhRes ], [ qw{ rhRes } ] ); sub groupsOf (&$@) { my $rcToRun = shift; my $groupsOf = shift; my $rcDoIt; $rcDoIt = sub { $rcToRun->( map shift, 1 .. ( @_ < $groupsOf ? @_ : $groupsOf ) ), @_ ? &$rcDoIt : (); }; &$rcDoIt; }

The output.

$rhRes = { 'tod' => '14', 'zip_code' => '02205', 'dow' => '0', 'area_code' => '617' };

I hope this is of interest.

Update: Here's a version using List::Util->pairs(), the output is essentially the same.

use strict; use warnings; use List::Util qw{ pairs }; use Data::Dumper; my $dbStr = q{special:1001:area_code:617|special:1001:zip_code:02205|special:10 +01:dow:0|special:1001:tod:14}; my $rhRes = { map { @{ $_ } } grep { $_->[ 0 ] ne q{special} } pairs split m{\||:}, $dbStr }; print Data::Dumper->Dumpxs( [ $rhRes ], [ qw{ rhRes } ] );

Cheers,

JohnGG