ž
不是指“ž”。它是U+009E PRIVACY MESSAGE,一个控制字符。(158 10 = 9E 16 )
"ž" 是U+017E LATIN SMALL LETTER Z WITH CARON,所以转义是ž
or ž
。
一些 Web 浏览器错误地解释具有 80..9F 16 (128..159 10 ) 中的 a 值的数字实体,将数字视为 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");