第3部分(Part 2 is here)(Part 1 is here)
以下是我正在使用的perl Mod:Unicode::String
我如何称呼它:
print "Euro: ";
print unicode_encode("€")."\n";
print "Pound: ";
print unicode_encode("£")."\n";
希望它返回此格式:
€ # Euro
£ # Pound
功能如下:
sub unicode_encode {
shift() if ref( $_[0] );
my $toencode = shift();
return undef unless defined($toencode);
print "Passed: ".$toencode."\n";
Unicode::String->stringify_as("utf8");
my $unicode_str = Unicode::String->new();
my $text_str = "";
my $pack_str = "";
# encode Perl UTF-8 string into latin1 Unicode::String
# - currently only Basic Latin and Latin 1 Supplement
# are supported here due to issues with Unicode::String .
$unicode_str->latin1($toencode);
print "Latin 1: ".$unicode_str."\n";
# Convert to hex format ("U+XXXX U+XXXX ")
$text_str = $unicode_str->hex;
# Now, the interesting part.
# We must search for the (now hex-encoded)
# Unicode escape sequence.
my $pattern =
'U\+005[C|c] U\+0058 U\+00([0-9A-Fa-f])([0-9A-Fa-f]) U\+00([0-9A-Fa-f])([0-9A-Fa-f]) U\+00([0-9A-Fa-f])([0-9A-Fa-f]) U\+00([0-9A-Fa-f])([0-9A-Fa-f])';
# Replace escapes with entities (beginning of string)
$_ = $text_str;
if (/^$pattern/) {
$pack_str = pack "H8", "$1$2$3$4$5$6$7$8";
$text_str =~ s/^$pattern/\&#x$pack_str/;
}
# Replace escapes with entities (middle of string)
$_ = $text_str;
while (/ $pattern/) {
$pack_str = pack "H8", "$1$2$3$4$5$6$7$8";
$text_str =~ s/ $pattern/\;\&#x$pack_str/;
$_ = $text_str;
}
# Replace "U+" with "&#x" (beginning of string)
$text_str =~ s/^U\+/&#x/;
# Replace " U+" with ";&#x" (middle of string)
$text_str =~ s/ U\+/;&#x/g;
# Append ";" to end of string to close last entity.
# This last ";" at the end of the string isn't necessary in most parsers.
# However, it is included anyways to ensure full compatibility.
if ( $text_str ne "" ) {
$text_str .= ';';
}
return $text_str;
}
我需要获得相同的输出,但也需要支持Latin-9字符,但Unicode :: String仅限于latin1。关于我如何解决这个问题的任何想法?
我还有其他几个问题,并且认为我对Unicode和编码有一定的了解,但也有时间问题。
感谢任何帮助我的人!
答案 0 :(得分:2)
正如您所知,Unicode :: String不是模块的合适选择。 Perl附带一个名为“Encode”的模块,可以完成您所需的一切。
如果你在Perl中有一个像这样的字符串:
my $euro = "\x{20ac}";
您可以将它转换为Latin-9中的字节字符串,如下所示:
my $bytes = encode("iso8859-15", $euro);
$bytes
变量现在将包含\ xA4。
或者你可以让Perl自动将输出转换为文件句柄,如下所示:
binmode(STDOUT, ":encoding(iso8859-15)");
您可以参考Encode模块的文档。此外,PerlIO描述了编码层。
我知道你决定不理会最后一条建议,但我会最后一次提供。 Latin-9是遗留编码。 Perl可以非常愉快地读取Latin-9数据并将其转换为UTF-8(使用binmode)。你不应该编写更多的软件来生成你应该从中迁移出来的Latin-9数据。