如何将正则表达式字符串替换值($ 1,$ 2等)映射到哈希?

时间:2011-11-29 21:13:43

标签: regex perl hash map

my (@keys,@values) = ($text =~ /\{IS\:([a-zA-Z0-9_-]+)\}(.*)\{\\IS\:([a-zA-Z0-9_-]+)\}/g);

应该匹配像这样的字符串

{IS:cow}moo{\IS:cow}
{IS:cow}moo{\IS:cow}    
{IS:dog}bark{\IS:dog}
{IS:dog}meow{\IS:dog} #probably not a dog

工作正常,除了所有$ 1,$ 2和$ 3的值都被转储到@keys ..所以我试图弄清楚如何让这些家伙成为$ 1 =>的漂亮哈希$ 2对...

对于完整的上下文,我 真的 喜欢做的是让regex表达式返回一个看起来像的数据结构(并附加一个数字的计数)钥匙被发现的次数)

{ 
  cow_1 => moo,
  cow_2 => moo,
  dog_1 => bark,
  dog_2 => meow,
}

有没有办法使用map {}函数来完成Regex?这样的事可能吗?

my %datahash = map { ( $1 eq $3 ) ? { $1 => $2 } : undef } @{ regex...};

$ 1等于$ 3以确保其匹配的标记(不需要递归检查这些标记不是嵌套的),如果是这样的话,使用$ 1作为键,$ 2作为值;

然后对于这些key =>中的每一个值对,我想替换

{IS:cow}moo{\IS:cow}
{IS:cow}moo{\IS:cow}   

{cow_1}
{cow_2}

然后如果$ cachedData {cow}为true,那么所有cow_ *将被替换为%datahash中的键......

3 个答案:

答案 0 :(得分:4)

$hash{$1} = $2 while 
        $text =~ /\{IS\:([a-zA-Z0-9_-]+)\}
                           (.*)
                  \{\\IS\:([a-zA-Z0-9_-]+)\}/gx;

(为了便于阅读而添加了/x修饰符)

答案 1 :(得分:2)

我从正则表达式中删除了无用的反斜杠和parens,并在char类中使用了快捷方式:

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

my $text = '{IS:cow}moo{\IS:cow}
{IS:cow}moo{\IS:cow}    
{IS:dog}bark{\IS:dog}
{IS:dog}meow{\IS:dog}';

my %cnt;
my %animals;
while ( $text =~ /\{IS:([\w-]+)}(.*)\{\\IS:[\w-]+}/g ){
    $animals{$1 . '_' . ++$cnt{$1}} = $2;
}

print "$_ => $animals{$_}\n" for sort keys %animals;

答案 2 :(得分:1)

  • $dataHash{cow}[$num]完全等同于$dataHash{"cow_$num"}
  • 使用$ dataHash {cow}以及与之相反,更容易获得任何牛 使用
    @dataHash{ grep { m/^cow_/ } keys %dataHash }
    “扫描”密钥
    • 它还将源数据('cow')与合成数据('1'分开,因为这是我第一次看到它。)

所以,我认为现在是让multi_hash发挥作用的好时机。

sub multi_hash {
    use List::Pairwise qw<mapp>;
    my %h;
    mapp { push @{ $h{ $a } }, $b } @_;
    return wantarray ? %h : \%h;
}

使用这个习惯用法,你可以制作一个哈希,类似于你想要的那样:

my %dataHash 
    = multi_hash(  map { m/[{]IS:([\w-]+)[}]([^{]+)[{]\\IS:\1[}]/ } @lines )
    ;

这给了我:

%dataHash: {
             cow => [
                      'moo',
                      'moo'
                    ],
             dog => [
                      'bark',
                      'meow'
                    ]
           }