将字符串中的预定义单词映射到perl中的散列

时间:2012-03-23 15:35:12

标签: regex perl hash

基本上我正在尝试将字符串中的某些关键字与附带的文本放在一个哈希中。

示例字符串:

!add-action-item :date 03/29/2012 :task Go to the bathroom :prio 1

代码片段:

when(/^!add-action-item/) {
        my ($date, $prio, $task) = $what =~ /:date\s(\d{2}\/\d{2}\/\d{4})\s|:prio\s(\d+)\s|:task\s(.*)/;
        print Dumper($date, $prio, $task);
    }

所以基本上我想要预定义的属性,比如:date,:prio,:task并将它们转换成

%ash = ( date => $date,
         prio => $prio,
         task => $task
       )

最终我想接受任何属性并将其置于一个键值对中,然后根据我关心的行为进行操作。对于perl来说,我非常苛刻,所以如果这是我在文档中遗漏的内容,我会道歉。

由于

3 个答案:

答案 0 :(得分:3)

您无法使用|捕获所有三个组。

修复正则表达式,然后从捕获组构建数据结构。

use strict;
use warnings;
use Data::Dumper;

my $string = '!add-action-item :date 03/29/2012 :task Go to the bathroom :prio 1';

if ( $string =~ /^!add-action-item/ ) {
    $string =~ m[
        \s+:date\s(\d{2}/\d{2}/\d{4})
        \s+:task\s(.*)
        \s+:prio\s(\d+)
    ]x;

    my $data = {
        date => $1,
        task => $2,
        prio => $3,
    };

    print Dumper $data;
}

__END__

$VAR1 = {
      'date' => '03/29/2012',
      'prio' => '1',
      'task' => 'Go to the bathroom'
};

答案 1 :(得分:2)

use Data::Dumper;
my @array = qw(Today stat bigone);
my %hash;
@hash{qw( date prio task )} = @array;
print Dumper \%hash;

$VAR1 = {
          'date' => 'Today',
          'prio' => 'stat',
          'task' => 'bigone'
        };

答案 2 :(得分:2)

我不喜欢按特定顺序查找特定字段的想法。例如,如果添加第4个字段,mugen kenichi的解决方案将失败。

由于更通用,这是一个更强大的解决方案:

my $cmd = '!add-action-item :date 03/29/2012 :task Go to the bathroom :prio 1';

for ($cmd) {
   /\G ! (\S+) /xgc or die;
   my $action = $1;

   my %args;
   for (;;) {
      last if /\G \s* \z /xgc;

      /\G \s+ :(\S+) /xgc or die;
      my $name = $1;

      /\G \s+ ([^\s:]\S*(?:\s+[^\s:]\S*)*) /xgc or die;
      my $val = $1;

      $args{$name} = $val;
   }

   # Do something with $action and %args here.
}

替代实施:

my $cmd = '!add-action-item :date 03/29/2012 :task Go to the bathroom :prio 1';

{
   my ($action, @args) = split /\s+:/, $cmd;

   $action =~ s/^!//;
   $action =~ s/\s+\z//;

   my %args;
   for my $arg (@args) {
      my ($name, $val) = split(' ', $arg, 2);
      $args{$name} = $val;
   }

   # Do something with $action and %args here.
}

例如,如果您使用

use Data::Dumper qw( Dumper );
local $Data::Dumper::Indent = 0;
local $Data::Dumper::Terse  = 1;
printf("action: %s\n", $action);
printf("args:   %s\n", Dumper(\%args));

你得到:

action: add-action-item
args:   {'date' => '03/29/2012','prio' => '1','task' => 'Go to the bathroom'}

Parse::RecDescent语法(未经测试):

parse    : command /\Z/ { $item[1] }
command  : action arg(s) { [ $item[1], { map @$_, @{$item[2]} } ] }
action   : /!\S+/ { substr($item[1], 1) }
arg_name : /:\S+/ { substr($item[1], 1) }
arg_val  : /[^\s:]\S*(?:\s+[^\s:]\S*)*/