【问题标题】:Perl - Unicode::String sub need to add/convert for Latin-9 supportPerl - Unicode::String sub 需要添加/转换以支持 Latin-9
【发布时间】:2010-06-18 18:42:12
【问题描述】:

第 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 和编码有所了解,但也有时间问题。

感谢任何帮助我的人!

【问题讨论】:

    标签: perl unicode encode


    【解决方案1】:

    正如您已经被告知的,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 数据的软件,而应该远离它。

    【讨论】:

    • mclean,再次感谢您对 Latin-9 和 Unicode::String 的输入。但由于我的工作要求我在这个项目中使用 Latin-9。查看他们提供给我的代码,他们也在使用 Unicode::String perl 模块。我也了解使用新的 encode() 并删除 Unicode::String 是多么理想,但由于项目要求不允许我这样做,所以我坚持使用它。我试图做的(这不起作用)是在 sub 中使用 encode() 而不是 latin1() 但我没有任何运气。再次感谢您的建议和获得的知识
    猜你喜欢
    • 2011-03-03
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 2011-01-11
    相关资源
    最近更新 更多