как конвертировать из кодировки gbk в кодировку utf-8 в Perl - PullRequest
1 голос
/ 24 мая 2011

У меня есть простой вопрос, который я не знаю, как решить в Perl. Я знаю, как конвертировать из utf-8 в GBK, например, из e4b8ad в d6d0. Но я не уверен, как идти назад, то есть, учитывая d6d0, откуда мне знать e4b8ad.

Пожалуйста, просветите меня! Большое спасибо.

Ответы [ 3 ]

3 голосов
/ 24 мая 2011

Если у вас есть шестнадцатеричные цифры, pack ваш друг. Ниже приводится сессия REPL. Примечания:

  • Чтобы изменить направление, упакуйте шестнадцатеричные цифры в октеты, декодируйте из октетов GB в строку символов, закодируйте строку символов в октеты UTF-8, распакуйте октеты в шестнадцатеричные цифры.
  • GBK заменено . Использование GB18030 (предоставленного Encode :: HanExtra в Perl) обязательно уже пять лет.

$ use Encode qw(decode encode); use Encode::HanExtra; use Devel::Peek qw(Dump);

$ 'e4b8ad'
e4b8ad                                  # hex digits

$ pack('H*', 'e4b8ad')
中

$ Dump(pack('H*', 'e4b8ad'))
SV = PV(0x3657680) at 0x36b7188
  REFCNT = 1
  FLAGS = (PADTMP,POK,pPOK)
  PV = 0x36c0768 "\344\270\255"\0           # octets of UTF-8 encoded data
  CUR = 3
  LEN = 8

$ decode('UTF-8', pack('H*', 'e4b8ad'))
中

$ Dump(decode('UTF-8', pack('H*', 'e4b8ad')))
SV = PV(0x326c3a0) at 0x36a50c8
  REFCNT = 1
  FLAGS = (TEMP,POK,pPOK,UTF8)
  PV = 0x3698a48 "\344\270\255"\0 [UTF8 "\x{4e2d}"]     # character string
  CUR = 3
  LEN = 8

$ encode('GB18030', decode('UTF-8', pack('H*', 'e4b8ad')))
"\xd6\xd0"

$ Dump(encode('GB18030', decode('UTF-8', pack('H*', 'e4b8ad'))))
SV = PV(0x36a2da0) at 0x36b6d98
  REFCNT = 1
  FLAGS = (TEMP,POK,pPOK)
  PV = 0x36db3e8 "\326\320"\0               # octets of GB18030 encoded data
  CUR = 2
  LEN = 8

$ unpack('H*', encode('GB18030', decode('UTF-8', pack('H*', 'e4b8ad'))))
d6d0                            # hex digits
1 голос
/ 24 мая 2011

Ответ на заданный вопрос:

use Encode qw( from_to );
my $gbk = "\xD6\xD0";
from_to(my $utf8 = $gbk, 'GB18030', 'UTF-8');  # E4 B8 AD

или

use Encode qw( decode encode );
my $gbk = "\xD6\xD0";
my $utf8 = encode('UTF-8', decode('GB18030', $gbk));  # E4 B8 AD

Однако более нормальный поток выглядит следующим образом:

open(my $fh_in,  '<:encoding(GB18030)', ...) or die ...;
open(my $fh_out, '>:encoding(UTF-8)',   ...) or die ...;

while (<$fh_in>) {
   ...
   print $fh_out ...;
   ...
}

Кодировать:: HanExtra должен быть установлен для Encode, чтобы найти кодировку.

0 голосов
/ 24 мая 2011
use Encode qw/encode decode/;
$utf8 = decode("euc-cn", $euc_cn); # ditto

Обычно вы также можете указать кодировку, когда открываете или закрываете FD, и он выполняет необходимые преобразования.

Работает как шарм:

perl -e 'open(X,">","/tmp/x"); print X chr(0xd6).chr(0xd0);close(X)'
perl -mEncode -e 'open(X,"<","/tmp/x"); $x=<X>; print Encode::decode("euc-cn",$x);' > /tmp/xx
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...