使用命名子表达式时是否可以复制%+哈希?

时间:2014-11-14 17:49:46

标签: regex perl

我有以下正则表达式来匹配readelf -Ws的输出:

my $regex = qr{  ^\s+(?'Num'\d+):
                  \s+(?'Value'\w+)
                  \s+(?'Size'(?:\d+|0x[0-9a-fA-f]+))
                  \s+(?'Type'\w+)
                  \s+(?'Bind'\w+)
                  \s+(?'Vis'\w+)
                  \s+(?'Ndx'\w+)
                  \s+(?'Name'\S+)
              }x;

......虽然它可能不完美,但它足以满足我的需求。

理想情况下,使用它的方式是:

while( <> ) {
  chomp;
  m{${regex}} || next;
  # an implicit assertion here is that length($+{Name}) > 0
  if(   $+{Type} =~ m{something}
     && $+{Bind} =~ m{something}
     ...

...但是,%+在第一个正则表达式后被破坏。我不确定如何制作%+基础的哈希副本。是否可能,如果是这样,我该怎么做?

显然可以做到以下几点:

while( <> ) {
  chomp;
  my ($Num, $Value, $Size, $Type, $Bind, $Vis, $Ndx, $Name) = ($_ =~ m{${regex}});
  next unless defined( $Name );

  if(   $Type =~ m{something}
     && $Bind =~ m{something}
     ...

...但我更喜欢使用命名子表达式,因为它可以帮助使正则表达式自我记录。

1 个答案:

答案 0 :(得分:2)

%captures = %+;

use Data::Dumper qw( Dumper );

local $_ = 'abc123';

my @captures;
while (/(?'Letters'\pL+)|(?'Digits'\pN+)/g) {
   my %captures = %+;
   push @captures, \%captures;
}

print(Dumper(\@captures));

$VAR1 = [
          {
            'Letters' => 'abc'
          },
          {
            'Digits' => '123'
          }
        ];

或者由于只存在已定义的字段,您可以使用

%captures = ( %captures, %+ );

$captures{$_} = $+{$_} for keys %+;

use Data::Dumper qw( Dumper );

local $_ = 'abc123';

my %captures;
while (/(?'Letters'\pL+)|(?'Digits'\pN+)/g) {
   %captures = ( %captures, %+ );
}

print(Dumper(\%captures));

$VAR1 = {
          'Letters' => 'abc',
          'Digits' => '123'
        };