在Date::Holidays::DK
模块中,某些丹麦假期的名称是用Latin1编码编写的。例如,1月1日是'Nytårsdag'。为了获得正确的utf8编码字符串,我应该对$x
下面做什么?
use Date::Holidays::DK;
my $x = is_dk_holiday(2011,1,1);
我在use utf8
之前/之后尝试了no utf8
和use Date::Holidays::DK
的各种组合,但它似乎没有任何效果。我也试图使用Encode的decode
,没有运气。更具体地说,
use Date::Holidays::DK;
use Encode;
use Devel::Peek;
my $x = decode("iso-8859-1",
is_dk_holiday(2011,1,1)
);
Dump($x);
print "January 1st is '$x'\n";
给出输出
SV = PV(0x15eabe8) at 0x1492a10
REFCNT = 1
FLAGS = (PADMY,POK,pPOK,UTF8)
PV = 0x1593710 "Nyt\303\245rsdag"\0 [UTF8 "Nyt\x{e5}rsdag"]
CUR = 10
LEN = 16
January 1st is 'Nyt sdag'
(t和s之间的字符无效)。
答案 0 :(得分:4)
在使用Date :: Holidays :: DK之前/之后使用utf8并且没有utf8,但它似乎没有任何效果。
正确。 utf8
pragma仅表示程序的源代码是用UTF-8编写的。
我也试过使用Encode的解码,没有运气。
你没有正确地理解这一点,你实际上是做对了。您现在拥有一串Perl字符并可以对其进行操作。
t和s之间的字符无效
你也解释了这个错误,实际上是å
字符。
您想输出UTF-8,因此您缺少编码步骤。
my $octets = encode 'UTF-8', $x;
print $octets;
请阅读http://p3rl.org/UNI以了解编码主题的介绍。你总是必须明确地或隐含地解码和编码。
答案 1 :(得分:2)
use utf8
只是对perl解释器/编译器的提示,即您的文件是UTF-8编码的。如果你有高位设置的字符串,它会自动将它们编码为unicode。
如果您有一个在iso-8859-1中编码的变量,则必须对其进行解码。然后您的变量采用内部unicode格式。这是utf8,但你不应该关心perl使用哪种编码。
现在,如果要打印这样的字符串,则需要将unicode字符串转换回字节字符串。您需要对此字符串执行encode
。如果你不手动编码perl
本身会将其编码回iso-8859-1。这是默认编码。
在打印变量$ x之前,您需要在其上执行$x = encode('UTF-8', $x)
。
为了正确处理UTF-8,您始终需要通过I / O解码()每个外部输入。而且你总是需要编码()所有离开程序的东西。
要更改默认的输入/输出编码,您可以使用类似的内容。
use utf8;
use open ':encoding(UTF-8)';
use open ':std';
第一行说你的源代码是用utf8编码的。第二行表示每个输入/输出应自动编码为utf8。重要的是要注意open()
也以utf8模式打开文件。如果使用二进制文件,则需要在句柄上调用binmode()
。
但第二行不会改变STDIN,STDOUT或STDERR的处理。第三行将改变这一点。
您可以使用模块utf8:all来简化此过程。但是了解这一切是如何在幕后工作总是好的。
纠正你的例子。一种可能的方法是:
#!/usr/bin/env perl
use Date::Holidays::DK;
use Encode;
use Devel::Peek;
my $x = decode("iso-8859-1",
is_dk_holiday(2011,1,1)
);
Dump($x);
print encode("UTF-8", "January 1st is '$x'\n");