Perl consideres ваш исходный файл должен быть закодирован в Latin-1, пока вы не скажете ему use utf8
. Если мы это сделаем, строка "ضثصثضصثشس"
не содержит некоторых перемежающихся байтов, а скорее представляет собой строку codepoints.
uri_escape_utf8
ожидает строку кодовых точек (не байтов!), Кодирует их, а затем URI-экранирует их. Ergo, правильная вещь, чтобы сделать
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_utf8
ти байтовой строки (что бы расшифровывает к арабским буквам) производит совершенно неправильно
%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";
Edit: Так вы использовали CP-1256, которая является непереносимой одного кодирования байт. Он не может кодировать произвольные символы Юникода, поэтому его следует избегать вместе с другими кодировками до Unicode. Вы не объявили свою кодировку, поэтому perl считает, что вы имели в виду латинский-1. Это означает, что то, что вы видели как "ضثصثضصثشس"
, было фактически байтовым потоком D6 CB D5 CB D6 D5 CB D4 D3
, который декодирует некоторый нецензурный барахл в латинском-1.
Редактировать: Итак, вы хотите декодировать аргументы командной строки. Модуль Encode::Locale
должен управлять этим.Перед тем как доступ к любым параметрам от @ARGV
, сделать
use Encode::Locale;
decode_argv(Encode::FB_CROAK); # possibly: BEGIN { decode_argv(...) }
или использовать locale
pseudoencoding, которые он обеспечивает:
my $decoded_string = decode "locale" $some_binary_data;
Используйте это как часть в общей стратегии декодирования всех входных и всегда кодирующая свой выход ,
Является ли ваш файл Perl кодированным как UTF-8? Вы использовали utf8? Если я это сделаю, я получаю «% D8% B6% D8% AB% D8% B5% D8% AB% D8% B6% D8% B5% D8% AB% D8% B4% D8% B3' - это правильно? (Это округляет правильно) – amon