Как я ищу массив Perl соответствующую строку?

Каков самый умный способ перерыть массив строк для соответствующей строки в Perl?

Один протест, я хотел бы, чтобы поиск был нечувствителен к регистру

так "aAa" был бы в ("aaa","bbb")

36
задан brian d foy 28 May 2010 в 12:50
поделиться

5 ответов

Думаю,

@foo = ("aAa", "bbb");
@bar = grep(/^aaa/i, @foo);
print join ",",@bar;

поможет.

29
ответ дан 27 November 2019 в 05:05
поделиться

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!"
29
ответ дан 27 November 2019 в 05:05
поделиться

Если вы будете выполнять много поисков в массиве, 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, или другие требования, которые могут быть выполнены с помощью нормализации (например, нечувствительность к регистру).

6
ответ дан 27 November 2019 в 05:05
поделиться
#!/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;
5
ответ дан 27 November 2019 в 05:05
поделиться

Это зависит от того, что вы хотите, чтобы поиск выполнял:

  • если вы хотите найти все совпадения , используйте встроенный 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 , если вы еще этого не делали.

143
ответ дан 27 November 2019 в 05:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: