use Mojo::Util; my $str = '<foo>bar<baz>&"'; my $res1 = Mojo::Util::html_unescape($str); my %ENTITIES = (lt => '<<<', gt => '>>>'); Mojo::Util::monkey_patch 'Mojo::Util', _entity => \&_entity2; my $res2 = Mojo::Util::html_unescape($str); print "res1: $res1\n"; print "res2: $res2\n"; sub _entity2 { my ($point, $name, $attr) = @_; print "_entity2 called...\n"; # Code point return chr($point !~ /^x/ ? $point : hex $point) unless defined $name; # Named character reference my $rest = my $last = ''; while (length $name) { return $ENTITIES{$name} . reverse $rest if exists $ENTITIES{$name} && (!$attr || $name =~ /;$/ || $last !~ /[A-Za-z0-9=]/); $rest .= $last = chop $name; } return '&' . reverse $rest; }