2009-08-18 38 views
2

我试图将Unicode字符的十六进制表示转换为它们所代表的字符。以下示例正常工作:如何在Perl中将不同的变量存储在字节中时,如何创建Unicode字符?

#!/usr/bin/perl 

use Encode qw(encode decode); 
binmode(STDOUT, ':encoding(utf-8)'); 

my $encoded = encode('utf8', "\x{e382}\x{af}"); 
eval { $encoded = decode('utf8', $encoded, Encode::FB_CROAK); 1 } 
or print("coaked\n"); 

print "$encoded\n"; 

但是,十六进制数字存储在3个变量中。

因此如果我用这个代替编码线:

my $encoded = encode('utf8', "\x{${byte1}${byte2}}\x{${byte3}}"); 

其中

my $byte1 = "e3"; my $byte2 = "82"; my $byte3 = "af"; 

,因为它试图在\ X立即评估,并认为$符号和{为字符它失败。

有谁知道如何解决这个问题。

回答

11

而不是

my $encoded = encode('utf8', "\x{${byte1}${byte2}}\x{${byte3}}"); 

您可以使用

my $encoded = encode('utf8', chr(hex($byte1 . $byte2)) . chr(hex($byte3))); 

hex()从十六进制的转换,并chr()返回给定代码点的Unicode字符。

[编辑:]

不相关的问题,但我注意到你在程序混合utf-8utf8。我不知道这是否是一个拼写错误,但你应该是一个这些在Perl中不一样的东西:
utf-8(带连字符,不区分大小写)是UTF-8标准所说的,而utf8(不区分大小写,也不区分大小写)是Perls内部编码,它更松散地定义(它允许代码点不是有效的unicode代码点)。一般来说,你应该坚持utf-8perlunifaq有详细说明)。

+1

谢谢!那就是我需要的。 – Tom 2009-08-18 09:53:50

6

trendel的答案似乎还不错,但Encode::Escape提供了一种替代的解决方案:

use Encode::Escape::Unicode; 

my $hex = '263a'; 
my $escaped = "\\x{" . $hex . "}\n"; 
print encode 'utf8', decode 'unicode-escape', $escaped; 
+1

也谢谢! – Tom 2009-08-18 09:54:22

0

首先,仔细想想为什么你结束了三个变量,$字节1,$字节2,$字节3,各持一个字节的数据,以十六进制表示的两个字符的字符串。你的程序的这一部分看起来很难,因为进一步糟糕的设计决定。修复这个糟糕的决定,而这部分代码自然会崩溃。

话虽这么说,你想做的事,我想,这是什么:


my $byte1 = "e3"; my $byte2 = "82"; my $byte3 = "af"; 
my $str = chr(hex($byte1 . $byte2)) . chr(hex($byte3)) 

编码的东西是一个红色的鲱鱼;你不应该担心你的程序中间的编码,只有当你做IO时。

我假设在上面,你想出去一个两个字符的字符串,U + E382其次是U + AF。这就是你真正要求的。但是,由于没有U + E382,因为它位于私人使用区域的中间,这可能不是您真正想要的。请尝试重新说明问题?也许提出一个更基本的问题,描述你想要达到的目标,而不是你试图去做什么?

+0

有3个变量,因为这是数据从Latex得到的方式。所以不能改变。该程序读入并立即输出结果,因此需要进行编码。其他人之前提供的解决方案正是需要的。 – Tom 2009-12-25 11:18:36

相关问题