/ / Como posso armazenar capturas de uma expressão regular Perl em variáveis ​​separadas? - matrizes, regex, perl, regex-group

Como posso armazenar capturas de uma expressão regular Perl em variáveis ​​separadas? - arrays, regex, perl, regex-group

Eu tenho uma regex:

/abc(def)ghi(jkl)mno(pqr)/igs

Como eu capturaria os resultados de cadaparênteses em 3 variáveis ​​diferentes, uma para cada parênteses? No momento, estou usando uma matriz para capturar todos os resultados, eles são seqüenciais, mas preciso analisá-los e a lista pode ser enorme.

@results = ($string =~ /abc(def)ghi(jkl)mno(pqr)/igs);

Respostas:

15 para resposta № 1

Sua pergunta é um pouco ambígua para mim, mas acho que você deseja fazer algo assim:

my (@first, @second, @third);
while( my ($first, $second, $third) = $string =~ /abc(def)ghi(jkl)mno(pqr)/igs) {
push @first, $first;
push @second, $second;
push @third, $third;
}

6 para resposta № 2

A partir da 5.10, você pode usar buffers de captura nomeados também:

#!/usr/bin/perl

use strict; use warnings;

my %data;

my $s = "abcdefghijklmnopqr";

if ($s =~ /abc (?<first>def) ghi (?<second>jkl) mno (?<third>pqr)/x ) {
push @{ $data{$_} }, $+{$_} for keys %+;
}

use Data::Dumper;
print Dumper %data;

Saída:

$ VAR1 = { "primeiro" => [ "def" ], "segundo" => [ "jkl" ], "terceiro" => [ "pqr" ] };

Para versões anteriores, você pode usar o seguinte, evitando a necessidade de adicionar uma linha para cada buffer capturado:

#!/usr/bin/perl

use strict; use warnings;

my $s = "abcdefghijklmnopqr";

my @arrays =  my(@first, @second, @third);

if (my @captured = $s =~ /abc (def) ghi (jkl) mno (pqr) /x ) {
push @{ $arrays[$_] }, $captured[$_] for 0 .. $#arrays;
}

use Data::Dumper;
print Dumper @arrays;

Saída:

$ VAR1 = [ "def" ]; $ VAR2 = [ "jkl" ]; $ VAR3 = [ "pqr" ];

Mas eu gosto de manter os dados relacionados em uma única estrutura de dados, por isso é melhor voltar a usar um hash. Isso requer uma matriz auxiliar, no entanto:

my %data;
my @keys = qw( first second third );

if (my @captured = $s =~ /abc (def) ghi (jkl) mno (pqr) /x ) {
push @{ $data{$keys[$_]} }, $captured[$_] for 0 .. $#keys;
}

Ou, se os nomes das variáveis ​​forem realmente first, second etc, ou se os nomes dos buffers não importam, mas apenas a ordem importa, você pode usar:

my @data;
if ( my @captured = $s =~ /abc (def) ghi (jkl) mno (pqr) /x ) {
push @{ $data[$_] }, $captured[$_] for 0 .. $#captured;
}

3 para resposta № 3

Uma maneira alternativa de fazer isso pareceria a resposta de ghostdog74, mas usando uma matriz que armazena referências de hash:

my @results;
while( $string =~ /abc(def)ghi(jkl)mno(pqr)/igs) {
my ($key1, $key2, $key3) = ($1, $2, $3);
push @results, {
key1 => $key1,
key2 => $key2,
key3 => $key3,
};
}

# do something with it

foreach my $result (@results) {
print "$result->{key1}, $result->{key2}, $result->{key3}n";
}

com a principal vantagem aqui de usar uma única estrutura de dados E ter um loop legível agradável.


2 para resposta № 4

@OP, quando os parênteses são capturados, você pode usar as variáveis ​​$ 1, $ 2 .... essas são referências anteriores

$string="zzzabcdefghijklmnopqrsssszzzabcdefghijklmnopqrssss";
while ($string =~ /abc(def)ghi(jkl)mno(pqr)/isg) {
print "$1 $2 $3n";
}

saída

$ perl perl.pl
def jkl pqr
def jkl pqr

0 para a resposta № 5

Você poderia ter três regexs diferentes cadacom foco em grupos específicos. Obviamente, você gostaria de apenas atribuir grupos diferentes a matrizes diferentes na regex, mas acho que sua única opção é dividir a regex.