Perl, сравнивая скаляр с массивом (с регулярным выражением?) - PullRequest
3 голосов
/ 21 ноября 2011

Я буду краток, чтобы не тратить ваше время;

Простая проблема, у меня есть множество, скажем, сотни собак

my @dogs = qw(Shepard Lab Dalmation Husky Chow Pitbull ...)

и я хочу сравнить его с одной собакой

my $doggy = "Shepard";

Довольно глупо, я знаю, но как мне это сделать?

# Regex match against array?
# (This doesnt even work but its how i would think of doing it)
if ($doggy =~ /@dogs/) {
print $doggy;
}

Спасибо за любые ответы заранее, я ценю, что вы, ребята, помогаете мне с, вероятно, действительно глупым вопросом. Спасибо

Ответы [ 7 ]

5 голосов
/ 21 ноября 2011

Я бы сделал это так:

my %hDogs = map { $_ => 1 } @dogs;

if(exists($hDogs{$doggy})) { ... }
4 голосов
/ 21 ноября 2011

Вы можете просто использовать grep:

my @dogs = qw(Shepard Lab Dalmation Husky Chow Pitbull);
my @wanted_dogs = grep {/^Shepard$/} @dogs;
print "@wanted_dogs\n";

Результат:

Shepard

Регулярное выражение можно изменить по своему усмотрению, и если вас интересует только первая подходящая собакавы найдете это в $wanted_dogs[0].

3 голосов
/ 21 ноября 2011

Оператор умного сопоставления :

use warnings;
use strict;

my @dogs = qw(Shepard Lab Dalmation Husky Chow Pitbull);
my $doggy = "Shepard";
if ($doggy ~~ @dogs) {
    print $doggy;
}
2 голосов
/ 21 ноября 2011

Если вы на самом деле не хотите совпадения с регулярным выражением и просто хотите посмотреть, есть ли точное совпадение где-то в списке, у вас есть несколько вариантов.

Смарт-совпадение - это относительно новый, но самый простой и , возможно, самый быстрый подход.

Классическими методами являются grep и List :: Util :: first .Вы можете настроить последние два, чтобы использовать регулярное выражение вместо eq, если вы хотите (например) сопоставить «Шепард», когда $dog - «Шеп».

use strict;
use warnings;
use v5.10;

my @dogs = qw(Shepard Lab Dalmation Husky Chow Pitbull);
my $dog = "Shepard";
my $cat = "Ocicat";

say "Smart match";
say $dog ~~ @dogs;
say $cat ~~ @dogs;

say "Grep";
say grep { $_ eq $dog } @dogs;
say grep { $_ eq $cat } @dogs;

say "List::Util";
use List::Util qw/first/;
say first { $_ eq $dog } @dogs;
say first { $_ eq $cat } @dogs;
1 голос
/ 21 ноября 2011

Существуют методы, использующие более новый оператор smart-match, но я предпочитаю старый классический:

my $dogs_re = join '|' => map quotemeta, @dogs;

if ($doggy =~ /$dogs_re/) {...}

Это создает чередование регулярных выражений типов вашей собаки после цитирования любых специальных символов регулярных выражений в именах.

Вы также можете скомпилировать регулярное выражение, если хотите:

$_ = qr/$_/ for $dogs_re;  

, который будет помещен после строки, определяющей $ dogs_re, и может дать некоторые преимущества в производительности, если вы будете использовать регулярное выражение много раз.

0 голосов
/ 24 февраля 2012

Попробуйте это,

$" = "|";
my @dogs=qw(Shepherd Lab Poodle Foo Bar);
my $temp = "@dogs";
my $dog = "Lab";
print "$1 found" if ($dog =~ /($temp)/);
0 голосов
/ 21 ноября 2011

Я бы, наверное, выбрал решение для поиска хеша для лучшего ответа, но есть много способов сделать это.Это одна из них.

Обратите внимание, что это имя нашей собаки используется в качестве регулярного выражения и перебирает его по списку, а не наоборот.

use v5.10; # needed for say
@dogs=qw(Shepherd Lab Poodle Foo Bar); 
$dog = 'Lab'; 
/\Q$dog\E/i and say for @dogs;"

Вы можете контролировать, насколько строгое соответствие:

/\Q$dog\E/i наименее строгий, игнорировать регистр, совпадать в любом месте слова.Например, «lab» будет соответствовать «Yellow Lab», «Labrador» и т. Д.

/^\Q$dog\E$/ является наиболее строгим, соответствует регистру, соответствует целому слову.

...