2

我试图将一些阿拉伯语转义到 LWP::UserAgent。我正在使用下面的脚本对此进行测试:

my $files = "/home/root/temp.txt";
unlink ($files);
open (OUTFILE, '>>', $files);
my $text = "ضثصثضصثشس";
print OUTFILE uri_escape_utf8($text)."\n";
close (OUTFILE);

但是,这似乎会导致以下情况:

%C3%96%C3%8B%C3%95%C3%8B%C3%96%C3%95%C3%8B%C3%94%C3%93

这是不正确的。任何指向我需要做什么才能正确转义的指针?

提前谢谢你的帮助。

问候,

奥利

4

1 回答 1

4

Perl 认为你的源文件被编码为 Latin-1,直到你告诉它use utf8. 如果我们这样做,字符串"ضثصثضصثشس"不包含一些混乱的字节,而是一串代码点

需要一串代码点(不是字节!),对uri_escape_utf8它们进行编码,然后对它们进行 URI 转义。因此,正确的做法是

use utf8;
use URI::Escape;
print uri_escape_utf8("ضثصثضصثشس"), "\n";

输出:%D8%B6%D8%AB%D8%B5%D8%AB%D8%B6%D8%B5%D8%AB%D8%B4%D8%B3


如果我们失败了use utf8,那么uri_escape_utf8会得到一个字节串(它被意外地以 UTF8 编码),所以我们应该使用uri_escape

die "This is the wrong way to do it";
use URI::Escape;
print uri_escape("ضثصثضصثشس"), "\n";

它产生与上述相同的输出——但只是偶然的。

使用uri_escape_utf8whith 字节串(将解码为阿拉伯字符)会产生完全错误的结果

%C3%98%C2%B6%C3%98%C2%AB%C3%98%C2%B5%C3%98%C2%AB%C3%98%C2%B6%C3%98%C2%B5%C3%98%C2%AB%C3%98%C2%B4%C3%98%C2%B3

因为这有效地对数据进行了双重编码。它与

use utf8;
use URI::Escape;
use Encode;
print uri_escape(encode "utf8", encode "utf8", "ضثصثضصثشس"), "\n";

编辑:所以你使用了 CP-1256,这是一种不可移植的单字节编码。它无法对任意 Unicode 字符进行编码,因此应避免与其他 pre-Unicode 编码一起使用。你没有声明你的编码,所以 perl 认为你的意思是 Latin-1。这意味着您所看到的"ضثصثضصثشس"实际上是 byte stream D6 CB D5 CB D6 D5 CB D4 D3,它在 Latin-1 中解码为一些不可打印的垃圾。

编辑:所以你想解码命令行参数。Encode::Locale模块应该管理这个。在从 访问任何参数之前@ARGV,请执行

use Encode::Locale;
decode_argv(Encode::FB_CROAK); # possibly: BEGIN { decode_argv(...) }

或使用locale它提供的伪编码:

my $decoded_string = decode "locale" $some_binary_data;

将此用作解码所有输入并始终对输出进行编码的整体策略的一部分。

于 2013-09-19T22:08:10.860 回答