私は正規表現を持っています:
/abc(def)ghi(jkl)mno(pqr)/igs
各括弧の結果を、括弧ごとに 1 つずつ、3 つの異なる変数に取り込むにはどうすればよいでしょうか? 現在、すべての結果をキャプチャするために 1 つの配列を使用しています。それらは順次出力されますが、それらを解析する必要があり、リストが巨大になる可能性があります。
@results = ($string =~ /abc(def)ghi(jkl)mno(pqr)/igs);
私は正規表現を持っています:
/abc(def)ghi(jkl)mno(pqr)/igs
各括弧の結果を、括弧ごとに 1 つずつ、3 つの異なる変数に取り込むにはどうすればよいでしょうか? 現在、すべての結果をキャプチャするために 1 つの配列を使用しています。それらは順次出力されますが、それらを解析する必要があり、リストが巨大になる可能性があります。
@results = ($string =~ /abc(def)ghi(jkl)mno(pqr)/igs);
あなたの質問は私には少しあいまいですが、次のようなことをしたいと思います:
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;
}
5.10 以降では、名前付きキャプチャ バッファも使用できます。
#!/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;
出力:
$VAR1 = { '最初' => [ 「デフ」 ]、 '秒' => [ 'JKL' ]、 '3番目' => [ 'pqr' ] };
以前のバージョンでは、キャプチャされたバッファごとに行を追加する必要がないように、次を使用できます。
#!/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;
出力:
$VAR1 = [ 「デフ」 ]; $VAR2 = [ 'JKL' ]; $VAR3 = [ 'pqr' ];
しかし、関連するデータを単一のデータ構造に保持するのが好きなので、ハッシュの使用に戻るのが最善です。ただし、これには補助配列が必要です。
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;
}
または、変数の名前が実際first
にsecond
などである場合、またはバッファの名前は重要ではなく、順序だけが問題である場合は、次を使用できます。
my @data;
if ( my @captured = $s =~ /abc (def) ghi (jkl) mno (pqr) /x ) {
push @{ $data[$_] }, $captured[$_] for 0 .. $#captured;
}
それを行う別の方法は、ghostdog74 の回答のように見えますが、ハッシュ参照を格納する配列を使用します。
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";
}
ここでの主な利点は、単一のデータ構造を使用することと、読みやすいループを持つことです。
@OP、括弧がキャプチャされると、変数 $1、$2 を使用できます....これらは後方参照です
$string="zzzabcdefghijklmnopqrsssszzzabcdefghijklmnopqrssss";
while ($string =~ /abc(def)ghi(jkl)mno(pqr)/isg) {
print "$1 $2 $3\n";
}
出力
$ perl perl.pl
def jkl pqr
def jkl pqr
それぞれが特定のグループに焦点を当てた 3 つの異なる正規表現を持つことができます。明らかに、正規表現の異なる配列に異なるグループを割り当てたいだけですが、唯一の選択肢は正規表現を分割することだと思います。