#!/usr/bin/perl use strict; my @repl_map; $repl_map[1] = { a => 'k', b => 'l', c => 'm' }; $repl_map[4] = { x => 'i', y => 'j', z => 'k' }; # positions 0,2,3 are undef (to be left unchanged) # positions >=5 (if present) will also be unchanged my $match = "^("; # note "^" to anchor match at offset 0 my $replc = ""; my $captr = 1; for my $pos ( 0 .. $#repl_map ) { if ( not defined( $repl_map[$pos] )) { $match .= "."; } else { warn sprintf( " mapping at pos %d: %s\n", $pos, join( ", ", map { "$_ => $repl_map[$pos]{$_}" } keys %{$repl_map[$pos]} )); $match .= ")([" . join("", sort keys %{$repl_map[$pos]}) . "])("; $replc .= sprintf( "\$%d\$repl_map[%d]{\$%d}", $captr, $pos, $captr+1 ); $captr += 2; } } chop $match; # remove trailing "(" warn " match: $match; replc: $replc\n\n"; my @strings = qw/aaaxxx bbbyyy ccczzz/; print "BEFORE: @strings\n"; for ( @strings ) { eval "s/$match/$replc/"; } print "AFTER: @strings\n";