Perl - Unicode :: String sub необходимо добавить / конвертировать для поддержки Latin-9 - PullRequest
0 голосов
/ 18 июня 2010

Часть 3 ( Часть 2 здесь ) ( Часть 1 здесь )

Вот Perl-мод, который я использую: 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 и Encodings, но также есть проблемы со временем.

Спасибо всемкто мне поможет!

1 Ответ

2 голосов
/ 18 июня 2010

Как вы уже сказали, Unicode :: String не является подходящим выбором модуля.Perl поставляется с модулем Encode, который может делать все, что вам нужно.

Если у вас есть строка символов в Perl, такая как:

my $euro = "\x{20ac}";

Вы можете преобразовать ее в строкубайты на латинице-9, такие как:

my $bytes = encode("iso8859-15", $euro);

Переменная $bytes теперь будет содержать \ xA4.

Или вы можете заставить Perl автоматически преобразовывать его вывод в дескриптор файла следующим образом:

binmode(STDOUT, ":encoding(iso8859-15)");

Вы можете обратиться к документации для модуля Кодирование .А также, PerlIO описывает уровень кодирования.

Я знаю, что вы полны решимости игнорировать этот последний совет, но я предложу его в последний раз.Latin-9 является устаревшей кодировкой.Perl может довольно счастливо читать данные Latin-9 и конвертировать их в UTF-8 на лету (используя binmode).Вам не следует писать больше программного обеспечения, которое генерирует данные Latin-9, которые вы должны перенести из него.

...