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



>我有以下正则表达式用于匹配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}
     ...

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

%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'
        };

最新更新