web-dev-qa-db-ja.com

Perlの配列に正規表現のキャプチャを保存するにはどうすればよいですか?

Perlで正規表現を使用しようとしています。私が疑問に思ったのは、式に一致するものをすべて配列に保存できるかどうかということでした。私は次を使用できることを知っています:($1,...,$n) = m/expr/g;しかし、それはあなたが探しているマッチの数を知っている場合にのみ使用できるようです。私が試してみました my @array = m/expr/g;しかし、それはうまくいかないようです。

ご協力いただきありがとうございます!

62
cskwrd

グローバルマッチ(/g)次に、リストコンテキストの正規表現は、キャプチャされたすべての一致を返します。単純に:

my @matches = ( $str =~ /pa(tt)ern/g )

たとえば、次のコマンド:

Perl -le '@m = ( "foo12gfd2bgbg654" =~ /(\d+)/g ); print for @m'

出力を与えます:

12
2
654
77
friedo

「リストコンテキストでの一致」の下の perldoc perlop の手動エントリを参照してください。

/ gオプションを使用しない場合、リストコンテキストのm //は、パターン内のかっこで一致した部分式で構成されるリストを返します。つまり、($ 1、$ 2、$ 3 ...)

/ g修飾子は、グローバルパターンマッチングを指定します。つまり、文字列内で可能な限り多くのマッチングを行います。動作は、コンテキストによって異なります。リストコンテキストでは、正規表現のキャプチャかっこで一致した部分文字列のリストを返します。括弧がない場合は、パターン全体に括弧があるかのように、一致したすべての文字列のリストを返します。

配列に割り当てるか、リストコンテキストで評価を実行することで、すべての一致を簡単に取得できます。

my @matches = ($string =~ m/Word/g);
17
Ether

PHPのpreg_match_allのように、すべての一致をグローバルに取得する必要がある場合があります。あなたの場合は、次のように書くことができます:

# a dummy example
my $subject = 'Philip Fry Bender Rodriguez Turanga Leela';
my @matches;
Push @matches, [$1, $2] while $subject =~ /(\w+) (\w+)/g;

use Data::Dumper;
print Dumper(\@matches);

印刷する

$VAR1 = [
          [
            'Philip',
            'Fry'
          ],
          [
            'Bender',
            'Rodriguez'
          ],
          [
            'Turanga',
            'Leela'
          ]
        ];
17
codeholic

これは自明の例だと思います。注意 /g最初の正規表現の修飾子:

$string = "one two three four";

@res = $string =~ m/(\w+)/g;
print Dumper(@res); # @res = ("one", "two", "three", "four")

@res = $string =~ m/(\w+) (\w+)/;
print Dumper(@res); # @res = ("one", "two")

左辺値がリストコンテキストにあることを確認する必要があることを忘れないでください。つまり、スカラー値を括弧で囲む必要があります。

($one, $two) = $string =~ m/(\w+) (\w+)/;
8
Flimm

必要なキャプチャグループの数がわかっている場合は、perが一致する場合、この単純なアプローチを使用できます。これは、2つのキャプチャグループの例として示しています。

次のような「データ」があるとします

my $mess = <<'IS_YOURS';
Richard     Rich
April           May
Harmony             Ha\rm
Winter           Win
Faith     Hope
William         Will
Aurora     Dawn
Joy  
IS_YOURS

次の正規表現で

my $oven = qr'^(\w+)\h+(\w+)$'ma;  # skip the /a modifier if using Perl < 5.14

以下の@boxで12個すべてをキャプチャできます(6ペア、not 8 ... Harmony escaped and Joy is missing)。

my @box = $mess =~ m[$oven]g;

ボックスの詳細を「ハッシュ」したい場合は、次のようにします。

my %hash = @box;

または、ボックスを完全にスキップすることもできますが、

my %hash = $mess =~ m[$oven]g;

%hashには以下が含まれていることに注意してください。順序は失われ、重複キー(存在する場合)は押しつぶされます。

(
          'April'   => 'May',
          'Richard' => 'Rich',
          'Winter'  => 'Win',
          'William' => 'Will', 
          'Faith'   => 'Hope',
          'Aurora'  => 'Dawn'
);
0
YenForYang