【问题标题】:Converting a sequence of bytes into proper characters将字节序列转换为正确的字符
【发布时间】:2017-12-14 11:06:17
【问题描述】:

我使用这个site 来转换这样的字节序列:

Рабыни

转换成这样的正确字符序列:

无忧无虑

该站点似乎将 UTF8 序列解码为其原始字符。出于某种原因,我的一些文件名已损坏,我需要将它们转换回原来的名称。

由于文件数量不少,我决定为此编写一个 perl 脚本。我试过这个

#!/usr/bin/perl
use utf8;
$str = "Рабыни.avi";
utf8::decode($str);
binmode STDOUT, ":utf8";
print "$str\n";

作为对一个文件名的测试。运行脚本时,我将输出重定向到文件。当我看到文件的内容时,我看到内容与输入字符串相同,并且没有进行任何转换。这是因为输出与站点为这样的序列转换的内容是一致的:

ангелов

我尝试使用 ActivePerl 在 Linux (Ubuntu) 和 Windows 上运行脚本,两者都给出了相同的结果。专注于Windows,您认为脚本的错误是什么?

谢谢

【问题讨论】:

  • 您的示例文本不完整,我收到“�абыни.avi”。另外,检查您的终端是否支持 UTF-8
  • 我没有找到你说我的样本测试不完整的意思。你的意思是什么示例文本?我尝试将输出重定向到文件。我也试过linux。似乎没有一个工作。
  • 如果我将您的脚本复制并粘贴到我的 linux 终端中,我会看到西里尔文文本。所以我认为这一定是windows支持的事情。
  • 是的,你说得对。在 cmd.exe 中,我看不到应该显示的西里尔文文本。但就输出重定向到文件而言,终端不依赖。终端只是用来运行 perl 脚本。但即使在这种情况下,输出文件也包含相同的输入。
  • 使用编码; $str = "ангелов.avi"; $str = decode('utf8',$str);打开(H,'>','pradeep.txt');打印 H $str;关闭 H;这对我有用。

标签: perl utf-8


【解决方案1】:

使用 UTF-8 编码 Рабыни 得到 D0.<b>A0</b>.D0.B0.D0.B1.D1.<b>8B</b>.D0.BD.D0.B8

但是,РабыниD0.<b>20</b>.D0.B0.D0.B1.D1.<b>2039</b>.D0.BD.D0.B8

主要问题是 utf8::decode($str); 失败,因为 Рабыни 不是有效的 UTF-8。 Рабыни 的编码已不可逆转地损坏。


对于 Windows,

#!/usr/bin/perl

my $terminal_enc_layer;
BEGIN {
    $terminal_enc_layer = $^O eq 'MSWin32'
        ? do { require Win32; ":encoding(cp".Win32::GetACP().")" }
        : ":locale";
}

use utf8;
use open ':std', $terminal_enc_layer;

use strict;
use warnings;

my $str = "\xD0\xA0\xD0\xB0\xD0\xB1\xD1\x8B\xD0\xBD\xD0\xB8";

utf8::decode($str)
   or die "Bad data";

print "$str\n";

【讨论】:

    猜你喜欢
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多