ž
「ž」は参照しません。それはU+009E PRIVACY MESSAGE、制御文字です。(158 10 = 9E 16)
「ž」はU+017E LATIN SMALL LETTER Z WITH CARONなので、エスケープはž
またはになりž
ます。
一部のWebブラウザーは、値が80..9F 16(128..159 10)の数値エンティティを誤って解釈し、その数値をUnicodeコードポイントのWindows-1252エンコーディングとして扱います。
| Grapheme | ř | ž |
+--------------------+-------------------+-------------------+
| Unicode Code Point | U+0159 (345) | U+017E (382) |
| Escape | ř (ř) | ž (ž) |
+--------------------+-------------------+-------------------+
| cp1252 encoding | --- | 9E (158) |
| Alternate escape* | --- | ž (ž) |
* — Non-standard and buggy behaviour.
このバグのある動作は、あなたが望むものです。その動作を実装するモジュールが表示されないため、独自にコーディングする必要があります。
use strict;
use warnings;
use open ':std', ':encoding(UTF-8)';
use HTML::Entities qw( );
use Encode qw( decode );
{
my %fixes =
map { chr($_) => decode('cp1252', chr($_)) }
0x80..0x9F;
sub decode_entities {
my $s_ref = defined(wantarray())
? do { my ($s) = @_; \$s }
: \$_[0];
$$s_ref =~ s{(
&\#
(?: 0*([1-9][0-9]*);?
| x0*([1-9A-Fa-f][0-9A-Fa-f]*);?
)
)}{
if (defined($2) && length($2) == 3 && exists($fixes{chr($2)})) {
$fixes{chr($2)}
} elsif (defined($3) && length($3) == 2 && exists($fixes{chr(hex($3))})) {
$fixes{chr(hex($3))}
} else {
$1
}
}exg;
HTML::Entities::decode_entities($$s_ref);
return $$s_ref;
}
}
print(decode_entities("Křižovnická 190"), "\n");