Perl:模块中的字符串文字为拉丁文1-我想要utf8
在Perl:模块中的字符串文字为拉丁文1-我想要utf8,perl,encoding,utf-8,perl-module,latin1,Perl,Encoding,Utf 8,Perl Module,Latin1,在Date::Holidays::DK模块中,某些丹麦节日的名称是用拉丁文1编码的。例如,1月1日是“Nytårsdag”。我应该如何处理下面的$x,以获得正确的utf8编码字符串 use Date::Holidays::DK; my $x = is_dk_holiday(2011,1,1); 在使用日期::节假日::DK之前/之后,我尝试了使用utf8和不使用utf8的各种组合,但似乎没有任何效果。我还尝试使用Encode的解码,但运气不好。更具体地说 use Date::Holidays:
Date::Holidays::DK
模块中,某些丹麦节日的名称是用拉丁文1编码的。例如,1月1日是“Nytårsdag”。我应该如何处理下面的$x
,以获得正确的utf8编码字符串
use Date::Holidays::DK;
my $x = is_dk_holiday(2011,1,1);
在使用日期::节假日::DK
之前/之后,我尝试了使用utf8
和不使用utf8
的各种组合,但似乎没有任何效果。我还尝试使用Encode的解码,但运气不好。更具体地说
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之间使用无效字符)。使用utf8只是提示perl解释器/编译器您的文件是UTF-8编码的。如果您有设置了高位的字符串,它将自动将它们编码为unicode 如果您有一个以iso-8859-1编码的变量,则必须对其进行解码。那么您的变量是内部unicode格式的。这是utf8,但您不应该关心perl内部使用哪种编码 现在,如果要打印这样的字符串,需要将unicode字符串转换回字节字符串。您需要对该字符串执行
编码。如果不手动执行编码,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的处理。第三行将改变这一点
您可能可以使用模块来简化此过程。但了解所有这些在幕后是如何运作的总是好的
纠正你的例子。一种可能的方法是:
#!/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");
在使用日期::节假日::DK之前/之后使用utf8和不使用utf8,但它似乎没有任何效果
对。utf8
pragma仅表示程序的源代码是用UTF-8编写的
我还尝试使用Encode的解码,但没有成功
你没有正确地认识到这一点,事实上你做了正确的事情。现在您有了一个Perl字符字符串,可以对其进行操作
在t和s之间使用无效字符
你也解释错了,它实际上是å
字符
您希望输出UTF-8,因此缺少编码步骤
my $octets = encode 'UTF-8', $x;
print $octets;
请阅读有关编码主题的介绍。您必须始终进行解码和编码,无论是显式还是隐式。我希望您删除关于is_utf8的段落。您知道更好的方法来检查字符串是否以unicode内部编码吗?然后我将替换it.ITYM来表示“内部编码为UTF-8编码”,因为某些编码为字符集(如Unicode)的内容没有任何意义。回答:你不应该在意,SvUTF8标志或它的缺失不能告诉你(这就是_utf8实际检查的内容)。程序员只需跟踪:我是否已经解码了传入的八位字节?我已经对输出字符数据进行编码了吗?Perl如何对字符数据进行内部编码是它自己的事情(比您意识到的要复杂得多),您不应该弄乱utf8模块中的函数。它的文档说明了这一点。如果您想编写一个正确处理unicode字符串的模块并与外界对话,那么您需要知道字符串是否用unicode编码(是的,unicode不是一种编码,在内部它是utf-8,但是用户不应该关心内部表示是什么,用户应该只关心它是否是unicode)当然,你也不关心Unicode,让使用你的模块的用户自己处理它,但是我不喜欢它。Perl有Unicode字符串,一个MODUL作者应该考虑它。我总是打开一个更好的方法。“不要这样做”。不是更好的方法。抱歉,但这根本不是真的。is_utf8
并不表示是否需要对某些内容进行编码。事实上,Perl无法知道字符串是否需要编码。如果需要,它可以自己进行编码。(我会详细揭穿您的说法,但这个框确实不适合解释任何内容。)至于怎么做,你应该在输入端对所有内容进行解码,在输出端对所有内容进行编码。如果你想处理编码和解码的字符串,你需要手动跟踪哪个是哪个。