へへ。:-) これは、過去数十回の Perl リリースにおける Unicode のサポートの増加と、より正確には、モジュール\C
で使用される正規表現機能に関係しています。背景を理解するには、2010 年の perl-unicode に関するこのスレッド (正規表現で \C エスケープを使用しないでください - なぜ使用しないのですか?)を読んでください。URI
URI::Escape
なぜURI
モジュール?でフォームや URL のエンコーディングを行うために使用されるためですHTTP::Request::Common
。
URI
一方、特にモジュールが非常に頻繁に使用されるため、この問題がいかにトリッキーであるかを思い出すために私が書いたスクリプトを次に示します。
use 5.010;
use utf8;
# Perl and URI.pm might behave differently when you encode your script in
# Latin1 and drop the utf8 pragma.
use Encode;
use URI;
use Test::More;
use constant C3A8 => 'text=%C3%A8';
use constant E8 => 'text=%E8';
diag "Perl $^V";
diag "URI.pm $URI::VERSION";
my $chars = 'è';
my $octets = encode 'iso-8859-1', $chars;
my $uri = URI->new('http:');
$uri->query_form( text => $chars );
is $uri->query, C3A8, C3A8;
my @exp;
given ( "$^V $URI::VERSION" ) {
when ( 'v5.12.3 1.56' ) { @exp = ( E8, C3A8 ) }
when ( 'v5.10.1 1.54' ) { @exp = ( C3A8, C3A8 ) }
when ( 'v5.10.1 1.58' ) { @exp = ( C3A8, C3A8 ) }
default { die 'not tested :-)' }
}
$uri->query_form( text => $octets );
is $uri->query, $exp[0], $exp[0];
utf8::upgrade $octets;
$uri->query_form( text => $octets );
is $uri->query, $exp[1], $exp[1];
done_testing;
だから私が得たもの(WindowsとCygwinで)は次のとおりです。
C:\Windows\system32 :: perl \Opt\Cygwin\tmp\uri.pl
# Perl v5.12.3
# URI.pm 1.56
ok 1 - text=%C3%A8
ok 2 - text=%E8
ok 3 - text=%C3%A8
1..3
と:
MiLu@Dago: ~/comp > perl /tmp/uri.pl
# Perl v5.10.1
# URI.pm 1.54
ok 1 - text=%C3%A8
ok 2 - text=%C3%A8
ok 3 - text=%C3%A8
1..3
アップデート
リクエストボディを手作りすることができます:
use utf8;
use Encode;
use LWP::UserAgent;
my $chars = 'ölè';
my $octets = encode( 'iso-8859-1', $chars );
my $body = 'text=' .
join '',
map { $o = ord $_; $o < 128 ? $_ : sprintf '%%%X', $o }
split //, $octets;
my $uri = 'http://localhost:8080/';
my $req = HTTP::Request->new( POST => $uri, [], $body );
print $req->as_string;
my $ua = LWP::UserAgent->new;
my $rsp = $ua->request( $req );
print $rsp->as_string;