我想从输入散列引用创建url。假设我给哈希引用
my $input_hash_ref = {
'1' => 'A',
'2' => 'B',
'3' => {
'4' => {
'5' => {
'6' => [
'ice cream','drink'
],
'7' => 'large'
}
'8' => 'perl'
'9' => 'rosy'
},
'10'=>'june'
},
};
然后将其转换为
1=A&2=B&3.4.5.6=ice cream|drinks&3.4.5.7=large&3.8=perl&3.9=rosy&10=june
需要帮助。
答案 0 :(得分:3)
我只是要说,你不应该使用join
编写带有简单实现的查询字符串。
use URI;
use URI::QueryParam;
my $u = URI->new("","http");
然后你可以简单地说:
$u->query_param_append("1" => "A", "2" => "B", ....);
甚至
$u->query_form_hash( %somedata );
请注意,这不会自动处理序列化嵌套的自定义架构,但它确实会保证您将发出任何服务器都能理解的有效查询字符串。
虽然您也可以使用Perl模块从深度嵌套的Hash转换为Flat哈希并再次返回:
您可以使用它来转换双方格式。
使用示例:
use strict;
use warnings;
use utf8;
use Data::SplitSerializer;
use Data::Dump qw(pp);
use URI;
use URI::QueryParam;
my $input_hash = {
'1' => 'A',
'2' => 'B',
'3' => {
'4' => {
'5' => {
'6' => [
'ice cream','drink'
],
'7' => 'large'
}
},
},
'8' => 'june',
'9' => "Challenging & Value",
};
my $flattened = Data::SplitSerializer->new( path_style => 'DZIL' )->serialize($input_hash);
pp $flattened;
my $uri = URI->new("http://example.com/thing?");
$uri->query_form_hash( $flattened );
printf "%s\n", $uri;
my $copy = URI->new( $uri . "" ); # simulate getting it server side
my $copy_hash = $copy->query_form_hash;
pp $copy_hash;
my $deep = Data::
SplitSerializer->new( path_style => 'DZIL' )->deserialize($copy_hash);
pp $deep;
示例输出:
{
"1" => "A",
"2" => "B",
"3.4.5.6[0]" => "ice cream",
"3.4.5.6[1]" => "drink",
"3.4.5.7" => "large",
"8" => "june",
"9" => "Challenging & Value",
}
http://example.com/thing?9=Challenging+%26+Value&3.4.5.6%5B1%5D=drink&2=B&8=june&3.4.5.6%5B0%5D=ice+cream&1=A&3.4.5.7=large
{
"1" => "A",
"2" => "B",
"3.4.5.6[0]" => "ice cream",
"3.4.5.6[1]" => "drink",
"3.4.5.7" => "large",
"8" => "june",
"9" => "Challenging & Value",
}
{
1 => "A",
2 => "B",
3 => { 4 => { 5 => { 6 => ["ice cream", "drink"], 7 => "large" } } },
8 => "june",
9 => "Challenging & Value",
}
答案 1 :(得分:1)
use URI::Escape;
sub serial {
my ($h, $p) = @_;
return join "&", map {
my $v = $h->{$_};
my $ref = ref($v);
my $isH = $ref eq "HASH";
my $pp = join ".", grep defined, $p, $_;
$v = $isH ? serial($v,$pp)
: $ref ? join("|", map uri_escape($_), @$v)
: uri_escape($v);
$isH ? $v : "$pp=$v";
}
sort keys %$h;
}
my $input_hash_ref = {
'1' => 'A',
'2' => 'B',
'3' => {
'4' => {
'5' => {
'6' => [
'ice cream','drink'
],
'7' => 'large'
}
},
},
'8' => 'june'
};
print serial($input_hash_ref);
输出
1=A&2=B&3.4.5.6=ice cream|drink&3.4.5.7=large&8=june
答案 2 :(得分:0)
sub c {
my ($v, $p) = @_;
my $r = ref($v);
return map { c($v->{$_}, $p ? $p . '.' . $_ : $_) } keys(%$v) if $r eq 'HASH';
return $p . '=' . join('|', @$v) if $r eq 'ARRAY';
return $p . '=' . $v;
}
say(join('&', c($input_hash_ref)));