我学习使用Datatables在我的网站上绘制动态表,使用服务器端数据作为表的源。数据表在查询中使用复杂的参数,我希望将其转换为适当的Perl数据结构。所以,查询字符串是这样的(为了清楚起见包裹成行):
columns[0][data]=status&
columns[0][name]=&
columns[0][searchable]=true&
columns[0][orderable]=true&
columns[0][search][value]=&
columns[0][search][regex]=false&
columns[1][data]=some&
columns[1][name]=&
columns[1][searchable]=true&
columns[1][orderable]=true&
columns[1][search][value]=&
columns[1][search][regex]=false&
columns[2][data]=title&
columns[2][name]=&
columns[2][searchable]=true&
columns[2][orderable]=true&
columns[2][search][value]=&
columns[2][search][regex]=false
会变得像:
@columns = ( {
data => 'status',
name => '',
searchable => 1,
orderable => 1,
search => {
value => '',
regex => 0,
}
},
{
data => 'true',
name => '',
searchable => 1,
orderable => 1,
search => {
value => '',
regex => 0,
}
},
{
data => 'title',
name => '',
searchable => 1,
orderable => 1,
search => {
value => '',
regex => 0,
}
},
);
实现它的最佳方法是什么?
EDIT。
此外,在这种特殊情况下,我使用CGI.pm
来检索查询参数,这为我提供了平面数据结构。
答案 0 :(得分:2)
use Data::Diver 'DiveVal';
my @columns;
my %translate = ( 'true' => 1, 'false' => 0 );
for my $param ( $query->param() ) {
if ( $param =~ /^columns/ ) {
my $value = $query->param($param);
DiveVal( \@columns, $param =~ /\[(.*?)\]/g )
= $translate{$value} // $value;
}
}
答案 1 :(得分:1)
假设您从CGI对象中提取了参数,那么以下内容可以正常工作:
use strict;
use warnings;
my %params = (
'columns[0][data]' => 'status',
'columns[0][name]' => '',
'columns[0][searchable]' => 'true',
'columns[0][orderable]' => 'true',
'columns[0][search][value]' => '',
'columns[0][search][regex]' => 'false',
'columns[1][data]' => 'some',
'columns[1][name]' => '',
'columns[1][searchable]' => 'true',
'columns[1][orderable]' => 'true',
'columns[1][search][value]' => '',
'columns[1][search][regex]' => 'false',
'columns[2][data]' => 'title',
'columns[2][name]' => '',
'columns[2][searchable]' => 'true',
'columns[2][orderable]' => 'true',
'columns[2][search][value]' => '',
'columns[2][search][regex]' => 'false',
);
my @columns;
while (my ($key, $val) = each %params) {
next if $key !~ /^columns/;
my @keys = $key =~ /\[(.*?)\]/g;
my $ref = $columns[shift @keys] ||= {};
$ref = $ref->{shift @keys} ||= {} while @keys > 1;
$ref->{$keys[0]} = $val;
}
use Data::Dump;
dd @columns;
输出:
(
{
data => "status",
name => "",
orderable => "true",
search => { regex => "false", value => "" },
searchable => "true",
},
{
data => "some",
name => "",
orderable => "true",
search => { regex => "false", value => "" },
searchable => "true",
},
{
data => "title",
name => "",
orderable => "true",
search => { regex => "false", value => "" },
searchable => "true",
},
)
答案 2 :(得分:0)
您可以尝试以下方式:
#! /usr/bin/perl
use warnings;
use strict;
my $qs="columns[0][data]=status&columns[0][name]=&columns[0][searchable]=true&columns[0][orderable]=true&columns[0][search][value]=&columns[0][search][regex]=false&columns[1][data]=some&columns[1][name]=&columns[1][searchable]=true&columns[1][orderable]=true&columns[1][search][value]=&columns[1][search][regex]=false&columns[2][data]=title&columns[2][name]=&columns[2][searchable]=true&columns[2][orderable]=true&columns[2][search][value]=&columns[2][search][regex]=false";
my @data=split ("&",$qs);
my @col;
for (@data) {
my ($val)=/=(.*)$/;
$_=~s/=.*//;
my @b=split(/\[(.*?)\]/);
my @c=@b[grep {$_% 2} 0..$#b];
if (@c==2) {
$col[$c[0]]->{$c[1]}=$val;
} else {
$col[$c[0]]->{$c[1]}{$c[2]}=$val;
}
}
或使用eval
获得更通用的解决方案:
for (@data) {
my ($val)=/=(.*)$/;
$_=~s/=.*//;
my @b=split(/\[(.*?)\]/);
my @c=@b[grep {$_% 2} 0..$#b];
my $cmd='$col[$c[0]]->';
for my $i (1..$#c) {
$cmd.='{$c['.$i.']}';
}
$cmd.='=$val';
eval ($cmd);
}