如何对西里尔字母进行URL编码和解码?

5

我在一个页面上有一个表单:

<form method="POST" accept-charset="UTF-8" action="index.cgi" name="TestForm">

其中一个输入字段“search_string”可以用于发送西里尔字符,如果发生这种情况,则URL字符串如下:

search_string=%41F%2F%424+%41F%41E%414%416%410%420%41A%410+%418%417+%421%412%418%41D

我该如何将其解码为在页面上发布的原始字符串?

看起来是十六进制数据,然后进行了URL编码。原始字符串是什么? - Øyvind Skaar
3个回答

5

正确的解决方案,包括空格:

use open ':std', ':encoding(UTF-8)';
use Encode;

my $escaped = '%41F%2F%424+%41F%41E%414%416%410%420%41A%410+%418%417+%421%412%418%41D';
(my $unescaped = $escaped) =~ s/\+/ /g;
$unescaped =~ s/%([[:xdigit:]]+)/chr hex $1/eg;
print $unescaped;
# П/Ф ПОДЖАРКА ИЗ СВИН

Credit goes to Renaud Bompuis for recognizing that these are Unicode code-points prefixed with %.
I would like to add that the encoding scheme used in the question is very unusual and I have not seen it before. Normally, one would expect the character string П/Ф ПОДЖАРКА ИЗ СВИН to be encoded as %D0%9F%2F%D0%A4+%D0%9F%D0%9E%D0%94%D0%96%D0%90%D0%A0%D0%9A%D0%90+%D0%98%D0%97+%D0%A1%D0%92%D0%98%D0%9D. That is to say, first the characters are encoded into UTF-8, and then the octets are percent-escaped. This scheme works with the answer from Dr.Kameleon.

2

一个可以保留原始字符串中的+和其他字符的解决方案:

my $s = '%41F%2F%424+%41F%41E%414%416%410%420%41A%410+%418%417+%421%412%418%41D';
$s =~ s/%([[:xdigit:]]+)/chr(hex($1))/eg;
print $s;

结果:

П/Ф+ПОДЖАРКА+ИЗ+СВИН

1

在你的脚本(index.cgi)中尝试一下:

use Encode;

那么...

$search_string = decode_utf8( $search_string );

另一个想法(如果您想要创建一个UTF8友好的CGI输入哈希):
require Encode;
require CGI;
my $query = CGI ->new;
my $form_input = {};  
foreach my $name ( $query ->param ) {
  my @val = $query ->param( $name );
  foreach ( @val ) {
    $_ = Encode::decode_utf8( $_ );
  }
  $name = Encode::decode_utf8( $name );
  if ( scalar @val == 1 ) {   
    $form_input ->{$name} = $val[0];
  } else {                      
    $form_input ->{$name} = \@val;  # save value as an array ref
  }
}

摘自:http://ahinea.com/en/tech/perl-unicode-struggle.html


使用 decode_utf8() 函数得到的字符串是“AF/B4 AFAEA4A6A0B0AAA0 A8A7 B1A2A8AD”,并不是我输入的原始 Cyrillic 字符串。 - goe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接