Каков самый умный способ перерыть массив строк для соответствующей строки в Perl?
Один протест, я хотел бы, чтобы поиск был нечувствителен к регистру
так "aAa"
был бы в ("aaa","bbb")
Думаю,
@foo = ("aAa", "bbb");
@bar = grep(/^aaa/i, @foo);
print join ",",@bar;
поможет.
Perl 5. 10+ содержит оператор 'smart-match' ~~
, который возвращает true, если определенный элемент содержится в массиве или хэше, и false, если нет (см. perlfaq4):
Приятно то, что он также поддерживает regexes, что означает, что ваше требование не учитывать регистр может быть легко выполнено:
use strict;
use warnings;
use 5.010;
my @array = qw/aaa bbb/;
my $wanted = 'aAa';
say "'$wanted' matches!" if /$wanted/i ~~ @array; # Prints "'aAa' matches!"
Если вы будете выполнять много поисков в массиве, AND соответствие всегда определяется как эквивалентность строк, то вы можете нормализовать ваши данные и использовать хэш.
my @strings = qw( aAa Bbb cCC DDD eee );
my %string_lut;
# Init via slice:
@string_lut{ map uc, @strings } = ();
# or use a for loop:
# for my $string ( @strings ) {
# $string_lut{ uc($string) } = undef;
# }
#Look for a string:
my $search = 'AAa';
print "'$string' ",
( exists $string_lut{ uc $string ? "IS" : "is NOT" ),
" in the array\n";
Позвольте мне подчеркнуть, что хэш-поиск хорош, если вы планируете выполнять много поисков в массиве. Кроме того, это будет работать только в том случае, если соответствие означает, что $foo eq $bar
, или другие требования, которые могут быть выполнены с помощью нормализации (например, нечувствительность к регистру).
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my @bar = qw(aaa bbb);
my @foo = grep {/aAa/i} @bar;
print Dumper \@foo;
Это зависит от того, что вы хотите, чтобы поиск выполнял:
если вы хотите найти все совпадения , используйте встроенный grep :
мой @matches = grep {/ pattern /} @list_of_strings;
, если вы хотите найти первое совпадение , используйте first
в List :: Util :
используйте List :: Util 'first';
мой $ match = first {/ pattern /} @list_of_strings;
, если вы хотите найти счетчик всех совпадений , используйте true
в List :: MoreUtils :
используйте List :: MoreUtils 'true ';
мой $ count = true {/ pattern /} @list_of_strings;
, если вы хотите узнать индекс первого совпадения , используйте first_index
в List :: MoreUtils :
используйте List :: MoreUtils ' first_index ';
мой $ index = first_index {/ pattern /} @list_of_strings;
, если вы хотите просто узнать , было ли совпадение , но вам все равно, какой это был элемент или его значение, используйте любой
в List :: Util :
используйте List :: Util 1.33 'any';
мой $ match_found = любой {/ шаблон /} @list_of_strings;
Все эти примеры делают схожие вещи по своей сути, но их реализации были сильно оптимизированы, чтобы быть быстрыми, и будут быстрее, чем любая реализация на чистом Perl, которую вы могли бы написать самостоятельно с помощью grep , ] map или для цикла .
Обратите внимание, что алгоритм выполнения цикла - это отдельный вопрос, чем выполнение отдельных совпадений.Чтобы сопоставить строку без учета регистра, вы можете просто использовать флаг i
в шаблоне: / pattern / i
. Вам обязательно стоит прочитать perldoc perlre , если вы еще этого не делали.