use warnings; use strict; use utf8; use open qw/:std :utf8/; use Devel::Peek qw/Dump/; use Data::Dump; my %_table; sub load_map { while () { chomp; my ($esc,$bin) = split / /, $_, 2; $_table{$bin} = $esc; } } sub escapeUTF8 { my ($sgml_r) = @_; $$sgml_r =~ s{([^\x00-\x7F])} { exists $_table{$1} ? $_table{$1} : '?' }eg; } load_map(); dd \%_table; use Test::More tests=>1; my $SGML='RÖCHLING '; Dump $SGML; escapeUTF8(\$SGML); is $SGML, 'RÖCHLING '; __DATA__ $ $ Ö Ö » »   #### 1..1 { "\$" => "$", "\xA0" => " ", "\xBB" => "»", "\xD6" => "Ö", } SV = PV(0x12fca50) at 0x134f698 REFCNT = 1 FLAGS = (POK,IsCOW,pPOK,UTF8) PV = 0x1361200 "R\303\226CHLING\302\240"\0 [UTF8 "R\x{d6}CHLING\x{a0}"] CUR = 11 LEN = 13 COW_REFCNT = 1 ok 1