3

誰かが助けてくれることを望んでいる問題があります(私がやろうとしていることを説明するために非常に単純化されています)...

私は3つの異なる配列を持っています:

my @array1 =  ("DOG","CAT","HAMSTER");
my @array2 =  ("DONKEY","FOX","PIG", "HORSE");
my @array3 =  ("RHINO","LION","ELEPHANT");

Web ページのコンテンツを含む変数もあります (WWW::Mechanize を使用):

my $variable = $r->content;

ここで、各配列の要素のいずれかが変数に含まれているかどうかを確認したいと思います。見つかった場合は、どの配列からのものかを確認したいと思います。

例えば

if ($variable =~ (any of the elements in @array1)) {
     print "FOUND IN ARRAY1";
} elsif ($variable =~ (any of the elements in @array2)) { 
     print "FOUND IN ARRAY2";
} elsif ($variable =~ (any of the elements in @array3)) {
     print "FOUND IN ARRAY3";
}

配列を使用して配列内の各要素を反復処理する最良の方法は何ですか? これを行うことができるより良い方法はありますか?

あなたの助けは大歓迎です、ありがとう

4

6 に答える 6

7

配列要素から正規表現を作成できますが、ほとんどの場合、メタ文字を無効にて、部分一致が得られないようにする必要があります。

my $rx = join('\b|\b', map quotemeta, @array1);

if ($variable =~ /\b$rx\b/) {
    print "matched array 1\n";
}

以下のように部分一致を取得したい場合は、単純にすべてのシーケンスFOXYを削除します。\b

デモンストレーション:

use strict;
use warnings;

my @array1 =  ("DOG","CAT","HAMSTER");
my @array2 =  ("DONKEY","FOX","PIG", "HORSE");
my @array3 =  ("RHINO","LION","ELEPHANT");

my %checks = (
    array1 => join('\b|\b', map quotemeta, @array1),
    array2 => join('\b|\b', map quotemeta, @array2),
    array3 => join('\b|\b', map quotemeta, @array3),
);

while (<DATA>) {
    chomp;
    print "The string: '$_'\n";
    for my $key (sort keys %checks) {
        print "\t";
        if (/\b$checks{$key}\b/) {
            print "does";
        } else {
            print "does not";
        }
        print " match $key\n";
    }
}

__DATA__
A DOG ATE MY RHINO
A FOXY HORSEY

出力:

The string: 'A DOG ATE MY RHINO'
        does match array1
        does not match array2
        does match array3
The string: 'A FOXY HORSEY'
        does not match array1
        does not match array2
        does not match array3
于 2013-04-11T14:16:08.367 に答える
2

まず第一に、変数名に整数サフィックスを追加していることに気付いた場合、配列を使用する必要があったと思います。

したがって、最初に単語セットを配列参照の配列に入れます。これは、一致した単語がどこから来たのかを特定するのに役立ちます。

次に、Regex::PreSufを使用して各単語リストからパターンを作成します。これは、正しい方法を常に忘れてしまうためです。

正規表現パターンで \bを使用すると、驚くべき結果が生じる可能性があることに注意してください。そのため、代わりに、コンテンツを個々の\w文字シーケンスに分割します。

4 番目に、「(WWW::Mechanize を使用して) Web ページからのコンテンツを含む変数もある」とあなたは言います。コメント内の単語を一致させますか? title属性で?そうでない場合は、HTML ドキュメントを解析して、完全なプレーン テキストを抽出するか、一致を特定の要素または要素のセット内に制限する必要があります。

次に、grepテキスト内の単語のリストから単語セットに含まれる単語を検索し、一致した単語セットにマップします。

#!/usr/bin/env perl

use strict; use warnings;

use Regex::PreSuf qw( presuf );

my @wordsets = (
    [ qw( DOG CAT HAMSTER ) ],
    [ qw( DONKEY FOX PIG HORSE ) ],
    [ qw( RHINO LION ELEPHANT ) ],
);

my @patterns = map {
    my $pat = presuf(@$_);
    qr/\A($pat)\z/;
} @wordsets;

my $content = q{Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis ELEPHANT exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in HAMSTER
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in DONKEY qui officia deserunt mollit anim id
est laborum.};

my @contents = split /\W+/, $content;

use YAML;
print Dump [
    map {
        my $i = $_;
        map +{$_ => $i },
        grep { $_ =~ $patterns[$i] } @contents
    } 0 .. $#patterns
];

ここでは、指定された単語セットに含まれるgrep { $_ =~ $patterns[$i] } @contents単語を抽出します@contents。次に、map +{$_ => $i }それらの単語を元の単語セットにマップします。外側mapは、各ワードセット パターンをループするだけです。

出力:

---
- ハムスター: 0
- ロバ: 1
- ゾウ: 2

つまり、各 hashref のキーが見つかった単語で、値が一致した単語セットである hashref のリストを取得します。

于 2013-04-11T15:40:31.883 に答える
2
my $re1 = join '|', @array1;
say "found in array 1" if $variable =~ /$re1/;

追加の配列ごとに繰り返します (または、正規表現の配列と用語の配列の配列を使用します)。

于 2013-04-11T13:57:02.633 に答える
0

モジュールを使いたい場合は、Regexp::Assembleが役立つかもしれません。正規表現の文字列を、個々の正規表現すべてに一致する 1 つの正規表現にまとめることができます。

于 2013-04-11T14:23:02.187 に答える
0

$variableは配列ではないと仮定します。その場合はforeachステートメントを使用します。

foreach my $item (@array1) {
    if ($item eq $variable) {
        print "FOUND IN ARRAY1";
    }
}

配列ごとに上記を繰り返します。つまり、array2、array3...

于 2013-04-11T13:56:49.953 に答える