如何将深层查询参数转换为Perl数据结构?

时间:2014-06-01 22:36:20

标签: perl datatables

我学习使用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来检索查询参数,这为我提供了平面数据结构。

3 个答案:

答案 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);
}