# Somewhere in an init function I define the hex value => string mapping # I find it easier to edit this way my %seed = ( '82' => ',', '83' => 'f', '84' => ',,', '85' => '...', '88' => '^', '89' => ' °/°°', '8B' => '<', '8C' => 'Oe', '91' => '`', '92' => '\'', '93' => '"', '94' => '"', '95' => '*', '96' => '-', '97' => '--', '98' => '~', '99' => 'TM', '9B' => '>', '9C' => 'oe', ); # Build a mapping of the hex code to string lookup table. # I find it to be less error prone than maintaining it manually my %msword_replace = (); while (my ($hex, $replace_with) = each %seed) { $msword_replace{chr(hex($hex))} = $replace_with; } # Define a list of hex codes that will be used as the search pattern # Then create a regex with alternation for these codes my @hex_codes = map {'\x' . $_} keys %seed; $msword_re = sprintf "(%s)", join('|', @hex_codes); # And then later when I need to do the replacing: $data =~ s/$msword_re/$msword_replace{$1}/g;