Perl将参数提取到hashref中

时间:2014-05-07 09:11:40

标签: regex perl

网址如下:

/products?includes=images(id,src),image(src),variants,options(title)

我想提取参数"包括"并将它们合并为一个这样的hashref:

$includes = {
  images => { fields => "id,src" },
  image => { fields => "src" },
  variants => undef,
  options => { fields => "title" }
}

我首先将其拆分为ARRAY,但不知道括号和主逗号中的子逗号。

2 个答案:

答案 0 :(得分:1)

#!/usr/bin/perl
#
use strict;
use warnings;

my $query=qq|images(id,src),image(src),variants,options(title)|;

sub rhash {
    my $v=shift;
    my %res=();
    for my $kv (grep(defined($_),$v=~/(\w+\([\w,]+\))|(\w+),/g)) {
        my ($k,$v);
        if ($kv=~/\(/) {
            ($k,$v)=$kv=~/([^(]+)\(([^)]+)\)/;
        } else {
            $k=$kv;
            $v=undef;
        }
    $res{$k}=$v;
    }
    return \%res;
}

use Data::Dumper;
print Dumper(rhash($query));

这似乎有点过于复杂,但它有效

这条线 for my $kv (grep(defined($_),$v=~/(\w+\([\w,]+\))|(\w+),/g)) 需要一点解释

/(\w+\([\w,]+\))|(\w+),/抓取任何alpha,后跟大括号或者只是alpha的组。在这一组之后有一个逗号。中间的|是交替运算符

定义的grep用作我构造的正则表达式似乎返回不需要的undef值。我相信它可以改进

答案 1 :(得分:1)

可以使用正则表达式来提取这些信息,但我相信专用(部分)解析URL的特定模块是解决此问题的更简单,更可靠的解决方案。

以下是使用正则表达式的一种可能解决方案:

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my $url = '/products?includes=images(id,src),image(src),variants,options(title)';

my %record;

my (undef, $para, $values) = split /\?|=/, $url;

while ($values =~ m/(\w+) (?: \( ([^\)]+) \) ,?)?/xg) {
    my ($key, $fields) = ($1, $2);
    $record{$para}->{$key} = { fields => $fields };
}

print "$url\n";
print Dumper(\%record);

输出:

$ perl t.pl 
/products?includes=images(id,src),image(src),variants,options(title)
$VAR1 = {
          'includes' => {
                          'variants' => {
                                          'fields' => undef
                                        },
                          'images' => {
                                        'fields' => 'id,src'
                                      },
                          'options' => {
                                         'fields' => 'title'
                                       },
                          'image' => {
                                       'fields' => 'src'
                                     }
                        }
        };