我现在要对编码方案发疯了。我将在下面陈述我的问题,请提供您的意见。
问题:我有一些输入字符串,如下面的代码中所述。最终所需的输出是"Křižovnická 190"。[ 你可以在这里解码它 ]。我正在使用perl模块来解码这些字符串。以下是我的测试代码:
use HTML::Entities;
binmode STDOUT,":utf8";
$a = "Křižovnická 190";
decode_entities($a);
print $a."n";
但是,我得到的输出是"Křiovnická 19",这意味着"ř"被正确解码,但"没有。我的问题是为什么?然后我尝试了"_decode_entities"方法,我们提供 entity2char 哈希,但仍然没有成功。
PS :我一定会在这里使用 Perl,因为其他遗留 API,请在这里帮助我
字符"ž"对应于Unicode中的ž
,而不是ž
。 158 是 cp1252 中"ž"的编码。
顺便说一句,克莱门汀很好。
为清楚起见:
| Grapheme | ř | ž |
|------------+-------------------+-------------------|
| Codepoint | U+0159 (345) | U+017E (382) |
| Escape | ř (ř) | ž (ž) |
|------------+-------------------+-------------------|
| UTF-8 | C5 99 (197 153) | C5 BE (197 190) |
| cp1252 | - | 9E (158) |
| latin2 | F8 (248) | BE (190) |
更新:
有关详细信息,请参阅维基百科上的 HTML 十进制字符呈现。重要的部分是:
(...) 对字符 128–159的引用通常由宽松的 Web 浏览器解释为对 Windows-1252 字符编码中分配给字节 128–159(十进制)的字符的引用。这违反了 HTML 和 SGML 标准,并且字符已经分配给更高的代码点,因此 HTML 文档作者应始终使用更高的代码点。例如,对于商标标志 (™),请使用
™
,而不是™
。
ž
不是指"ž"。 它是 U+009E 隐私消息,一个控制字符。(15810 = 9E16)
"ž"是 U+017E 拉丁小写字母 Z 和卡隆,所以转义将是ž
或ž
。
某些 Web 浏览器错误地解释 80..9F 16 (128..15910) 中值为 of 的数字实体,将该数字视为 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");