# $Id: Entities.pm,v 1.25 2003/01/19 04:12:43 gisle Exp $
HTML::Entities - Encode or decode strings with HTML entities
$a = "Våre norske tegn bør æres";
encode_entities($a, "\200-\377");
$input = "vis-à-vis Beyoncé's naïve papier-mâché résumé";
print encode_entities($in), "\n"
vis-à-vis Beyoncé's naïve papier-mâché résumé
This module deals with encoding and decoding of strings with HTML
character entities. The module provides the following functions:
=item decode_entities($string)
This routine replaces HTML entities found in the $string with the
corresponding ISO-8859-1 character, and if possible (under perl 5.7
or later) will replace to Unicode characters. Unrecognized
This routine is exported by default.
=item encode_entities($string, [$unsafe_chars])
This routine replaces unsafe characters in $string with their entity
representation. A second argument can be given to specify which
characters to consider unsafe (i.e., which to escape). The default set
of characters to encode are control chars, high-bit chars, and the
C<< < >>, C<< & >>, C<< > >>, and C<< " >>
characters. But this, for example, would encode I<just> the
C<< < >>, C<< & >>, C<< > >>, and C<< " >> characters:
$escaped = encode_entities($input, '<>&"');
This routine is exported by default.
=item encode_entities_numeric($string, [$unsafe_chars])
This routine works just like encode_entities, except that the replacement
entities are always C<&#xI<hexnum>;> and never C<&I<entname>;>. For
example, C<escape_entities("r\xF4le")> returns "rôle", but
C<escape_entities_numeric("r\xF4le")> returns "rôle".
This routine is I<not> exported by default. But you can always
export it with C<use HTML::Entities qw(encode_entities_numeric);>
or even C<use HTML::Entities qw(:DEFAULT encode_entities_numeric);>
All these routines modify the string passed as the first argument, if
called in a void context. In scalar and array contexts, the encoded or
decoded string is returned (without changing the input string).
If you prefer not to import these routines into your namespace, you can
$decoded = HTML::Entities::decode($a);
$encoded = HTML::Entities::encode($a);
$encoded = HTML::Entities::encode_numeric($a);
The module can also export the %char2entity and the %entity2char
hashes, which contain the mapping from all characters to the
corresponding entities (and vice versa, respectively).
Copyright 1995-2003 Gisle Aas. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
use vars
qw(@ISA @EXPORT @EXPORT_OK $VERSION);
use vars qw(%entity2char %char2entity);
@EXPORT = qw(encode_entities decode_entities _decode_entities);
@EXPORT_OK = qw(%entity2char %char2entity encode_entities_numeric);
$VERSION = sprintf("%d.%02d", q$Revision: 1.25 $ =~ /(\d+)\.(\d+)/);
sub Version { $VERSION; }
require HTML::Parser; # for fast XS implemented decode_entities
# Some normal chars that have special meaning in SGML context
'gt' => '>', # greater than
quot => '"', # double quote
apos => "'", # single quote
# PUBLIC ISO 8879-1986//ENTITIES Added Latin 1//EN//HTML
AElig => 'Æ', # capital AE diphthong (ligature)
Aacute => 'Á', # capital A, acute accent
Acirc => 'Â', # capital A, circumflex accent
Agrave => 'À', # capital A, grave accent
Aring => 'Å', # capital A, ring
Atilde => 'Ã', # capital A, tilde
Auml => 'Ä', # capital A, dieresis or umlaut mark
Ccedil => 'Ç', # capital C, cedilla
ETH => 'Ð', # capital Eth, Icelandic
Eacute => 'É', # capital E, acute accent
Ecirc => 'Ê', # capital E, circumflex accent
Egrave => 'È', # capital E, grave accent
Euml => 'Ë', # capital E, dieresis or umlaut mark
Iacute => 'Í', # capital I, acute accent
Icirc => 'Î', # capital I, circumflex accent
Igrave => 'Ì', # capital I, grave accent
Iuml => 'Ï', # capital I, dieresis or umlaut mark
Ntilde => 'Ñ', # capital N, tilde
Oacute => 'Ó', # capital O, acute accent
Ocirc => 'Ô', # capital O, circumflex accent
Ograve => 'Ò', # capital O, grave accent
Oslash => 'Ø', # capital O, slash
Otilde => 'Õ', # capital O, tilde
Ouml => 'Ö', # capital O, dieresis or umlaut mark
THORN => 'Þ', # capital THORN, Icelandic
Uacute => 'Ú', # capital U, acute accent
Ucirc => 'Û', # capital U, circumflex accent
Ugrave => 'Ù', # capital U, grave accent
Uuml => 'Ü', # capital U, dieresis or umlaut mark
Yacute => 'Ý', # capital Y, acute accent
aacute => 'á', # small a, acute accent
acirc => 'â', # small a, circumflex accent
aelig => 'æ', # small ae diphthong (ligature)
agrave => 'à', # small a, grave accent
aring => 'å', # small a, ring
atilde => 'ã', # small a, tilde
auml => 'ä', # small a, dieresis or umlaut mark
ccedil => 'ç', # small c, cedilla
eacute => 'é', # small e, acute accent
ecirc => 'ê', # small e, circumflex accent
egrave => 'è', # small e, grave accent
eth => 'ð', # small eth, Icelandic
euml => 'ë', # small e, dieresis or umlaut mark
iacute => 'í', # small i, acute accent
icirc => 'î', # small i, circumflex accent
igrave => 'ì', # small i, grave accent
iuml => 'ï', # small i, dieresis or umlaut mark
ntilde => 'ñ', # small n, tilde
oacute => 'ó', # small o, acute accent
ocirc => 'ô', # small o, circumflex accent
ograve => 'ò', # small o, grave accent
oslash => 'ø', # small o, slash
otilde => 'õ', # small o, tilde
ouml => 'ö', # small o, dieresis or umlaut mark
szlig => 'ß', # small sharp s, German (sz ligature)
thorn => 'þ', # small thorn, Icelandic
uacute => 'ú', # small u, acute accent
ucirc => 'û', # small u, circumflex accent
ugrave => 'ù', # small u, grave accent
uuml => 'ü', # small u, dieresis or umlaut mark
yacute => 'ý', # small y, acute accent
yuml => 'ÿ', # small y, dieresis or umlaut mark
# Some extra Latin 1 chars that are listed in the HTML3.2 draft (21-May-96)
copy => '©', # copyright sign
reg => '®', # registered sign
nbsp => "\240", # non breaking space
# Additional ISO-8859/1 entities listed in rfc1866 (section 14)
'not' => '¬', # not is a keyword in perl
'times' => '×', # times is a keyword in perl
# Make the opposite mapping
while (my($entity, $char) = each(%entity2char)) {
$char2entity{$char} = "&$entity;";
delete $char2entity{"'"}; # only one-way decoding
# Fill in missing entities
next if exists $char2entity{chr($_)};
$char2entity{chr($_)} = "&#$_;";
my %subst; # compiled encoding regexps
$array = \@_; # modify in-place
s/(&\#(\d+);?)/$2 < 256 ? chr($2) : $1/eg;
s/(&\#[xX]([0-9a-fA-F]+);?)/$c = hex($2); $c < 256 ? chr($c) : $1/eg;
s/(&(\w+);?)/$entity2char{$2} || $1/eg;
wantarray ? @$array : $array->[0];
$ref = \$_[0]; # modify in-place
if (defined $_[1] and length $_[1]) {
unless (exists $subst{$_[1]}) {
# Because we can't compile regex we fake it with a cached sub
my $code = "sub {\$_[0] =~ s/([$_[1]])/\$char2entity{\$1} || num_entity(\$1)/ge; }";
$subst{$_[1]} = eval $code;
die( $@ . " while trying to turn range: \"$_[1]\"\n "
# Encode control chars, high bit chars and '<', '&', '>', '"'
$$ref =~ s/([^\n\r\t !\#\$%\'-;=?-~])/$char2entity{$1} || num_entity($1)/ge;
sub encode_entities_numeric {
return &encode_entities; # a goto &encode_entities wouldn't work
sprintf "&#x%X;", ord($_[0]);
*encode = \&encode_entities;
*encode_numeric = \&encode_entities_numeric;
*encode_numerically = \&encode_entities_numeric;
*decode = \&decode_entities;