【问题标题】:Perl Text::CSV_XS Encoding IssuesPerl Text::CSV_XS 编码问题
【发布时间】:2010-07-24 20:28:48
【问题描述】:

我在 Perl 中遇到了 Unicode 字符问题。当我从网络接收数据时,我经常会收到√¢¬Ä¬ú√¢¬Ç¬¨ 之类的字符。第一个是引号,第二个是欧元符号。

现在我可以轻松地在 Perl 中替换正确的值并将正确的单词打印到屏幕上,但是当我尝试输出到 .CSV 文件时,我所做的所有替换都是徒劳的,而且我的 . CSV 文件。 (引号有效,猜测是因为它是一个通用字符)。 Numéro 也会给 Numéro。例子不胜枚举。

我写了一个小程序来尝试解决这个问题,但不确定问题是什么。我在另一个堆栈溢出线程上读到,您可以在 Excel 中导入 .CSV 并选择 UTF8 编码,但此选项不会为我弹出。我想知道我是否可以将其编码为 Excel 的本机字符集(UTF16BE???),或者是否有其他解决方案。我在这个短程序上尝试了许多变体,让我再说一遍,它只是为了测试 Unicode 问题,而不是合法程序的一部分。谢谢。

use strict;
use warnings;
require Text::CSV_XS;
use Encode qw/encode decode/;

my $text = 'Numéro Numéro Numéro Orkos Capital SAS (√¢¬Ä¬úOrkos√¢¬Ä¬ù) 325M√¢¬Ç¬¨ in 40 companies headquartered';

print("$text\n\n\n");

$text =~ s/“|”/"/sig;
$text =~ s/’s/'s/sig;
$text =~ s/√¢¬Ç¬¨/€/sig;
$text =~ s/√¢¬Ñ¬¢/®/sig;
$text =~ s/ / /sig;

print("$text\n\n\n");

my $CSV = Text::CSV_XS->new ({ binary => 1, eol => "\n" }) or die "Cannot use CSV: ".Text::CSV->error_diag();

open my $OUTPUT, ">:encoding(utf8)", "unicode.csv" or die "unicode.csv: $!";

my @row = ($text);

$CSV->print($OUTPUT, \@row);
$OUTPUT->autoflush(1);

这两行我也试过了,没用:

$text = decode("Guess", $text);
$text = encode("UTF-16BE", $text);

【问题讨论】:

    标签: perl excel unicode character-encoding


    【解决方案1】:

    首先,您的字符串以MacRoman 编码。当您将它们解释为字节序列时,第二个结果为C3 A2 C2 82 C2 AC。这看起来像 UTF-8,解码后的形式是E2 82 AC。这又看起来像 UTF-8,当你解码它时,你会得到。所以你需要做的是:

    $step1 = decode("MacRoman", $text);
    $step2 = decode("UTF-8", $step1);
    $step3 = decode("UTF-8", $step2);
    

    不要问我这个编码最初是通过哪些神秘的方式创建的。你的第一个字符解码为U+201C,这确实是LEFT DOUBLE QUOTATION MARK

    注意:如果您使用的是 Mac,则可能不需要第一个解码步骤,因为编码仅在“表示层”中(当您将 Perl 源代码复制到 HTML 表单中并且您的浏览器为您进行了编码翻译),而不是在数据本身中。

    【讨论】:

    • 当我尝试这个时,我收到以下错误:无法在 /Library/Perl/Updates/5.10.0/darwin-thread-multi-2level/Encode.pm 第 174 行解码带有宽字符的字符串。 “宽字符”是什么意思?我也在 Mac 上。
    • 通常,当您decode 某事时,您会从字节序列变为字符序列。 “宽字符”错误消息告诉您您已经有一个字符序列。这是一个安全网,可以防止你做你通常不想做的事情。
    • 如果你不是用 MacRoman 编码而是用 UTF-8 保存你的 Perl 程序,也许会有所帮助。还是您已经这样做了?
    【解决方案2】:

    所以我找到了答案,Roland Illig 的评论帮助我到达了那里(再次感谢!)。多次解码会导致宽字符错误,因此不应进行。

    这里的关键是解码 UTF-8 文本,然后用 MacRoman 对其进行编码。要将 .CSV 文件发送给我的 Windows 朋友,我必须先将其另存为 .XLSX,以免编码再次变得混乱。

    $text =~ s/√¢¬Ä¬ú|√¢¬Ä¬ù/"/sig; $text =~ s/√¢¬Ä¬ôs/'s/sig; $text =~ s/√¢¬Ç¬¨/€/sig; $text =~ s/√¢¬Ñ¬¢/®/sig; $text =~ s/√Ǭ†/ /sig; $text = decode("UTF-8", $text); print("$文本\n\n\n"); 我的 $CSV = Text::CSV_XS->new ({ binary => 1, eol => "\n" }) 或死“不能使用 CSV:”.Text::CSV->error_diag(); 打开我的 $OUTPUT, ">:encoding(MacRoman)", "unicode.csv" or die "unicode.csv: $!";

    【讨论】:

      猜你喜欢
      • 2013-06-02
      • 1970-01-01
      • 2013-01-24
      • 2019-05-17
      • 2017-07-14
      • 1970-01-01
      • 1970-01-01
      • 2018-10-29
      • 2013-05-17
      相关资源
      最近更新 更多