我从XML文件中提取字符串,即使它应该是纯UTF-8,但事实并非如此。我的想法是
#!/usr/bin/perl
use warnings;
use strict;
use Encode qw(decode encode);
use Data::Dumper;
my $x = "m\x{e6}gtig";
my $y = "m\x{c3}\x{a6}gtig";
my $a = encode('UTF-8', $x);
my $b = encode('UTF-8', $y);
print Dumper $x;
print Dumper $y;
print Dumper $a;
print Dumper $b;
if ($x eq $y) { print "1\n"; }
if ($x eq $a) { print "2\n"; }
if ($a eq $y) { print "3\n"; }
if ($a eq $b) { print "4\n"; }
if ($x eq $b) { print "5\n"; }
if ($y eq $b) { print "6\n"; }
输出
$VAR1 = 'm�gtig';
$VAR1 = 'mægtig';
$VAR1 = 'mægtig';
$VAR1 = 'mægtig';
3
认为只有latin1字符串会增加其长度,但编码已经是UTF-8也会使它更长。所以我无法通过这种方式检测到latin1与UTF-8。
问题
我想最终总是使用UTF-8字符串,但是如何检测它是latin1还是UTF-8,所以我只转换latin1字符串?
如果字符串是UTF-8,那么能够得到是/否。
答案 0 :(得分:7)
由于UTF-8的某些属性,使用iso-8859-1编码的文本不太可能是有效的UTF-8,除非它使用两种编码 [1] 进行相同的解码。
因此,解决方案是尝试使用UTF-8对其进行解码。如果失败,请使用iso-8859-1对其进行解码。由于使用iso-8859-1进行解码是一种无操作,我将跳过这一步。
utf8 :: implementation:
my $decoded_text = $utf8_or_latin1;
utf8::decode($decoded_text);
Encode :: implementation:
use Encode qw( decode_utf8 );
my $decoded_text =
eval { decode_utf8($utf8_or_latin1, Encode::FB_CROAK|Encode::LEAVE_SRC) }
// $utf8_or_latin1;
现在,你说你想要UTF-8。 UTF-8是通过编码解码文本获得的。
utf8 :: implementation:
my $utf8 = $decoded_text;
utf8::encode($utf8);
Encode :: implementation:
use Encode qw( encode_utf8 );
my $utf8 = encode_utf8($decoded_text);
注释
假设文本是有效的UTF-8或有效的iso-8859-1,如果满足以下所有条件,我的解决方案只会猜错:
(< 80> ..< 9F>是未分配或不可打印的控制字符,不确定是哪个。)
换句话说,该代码非常可靠。