Как я могу определить, находится ли значение в массиве Perl? - PullRequest
1 голос
/ 21 сентября 2010

Я использую этот небольшой фрагмент, чтобы определить, хранится или нет URL-адрес в массиве:

if( $self->{_local} eq "true" && ! grep {m|^$new_href?$|} @m_href_array ) {
    push( @m_href_array, $new_href );
    push( @href_array, $new_href );
}

Кажется, он работает, но затем мой код выдает ошибку:

Sequence (?$...) not implemented in regex; marked by <-- HERE in m/^javascript:SearchGo(?$ <-- HERE / at C:/Perl/site/lib/ACTC.pm line 152, <> line 1.

Кто-нибудь может объяснить, почему это происходит?

Ответы [ 5 ]

6 голосов
/ 21 сентября 2010

При поиске строки в массиве вы можете просто использовать eq вместо регулярного выражения:

grep { $_ eq $new_href } @m_href_array

Однако, если вам действительно нужно использовать регулярное выражение (например, вы ищете строку, соответствующую подстроке в массиве, вы должны всегда заключать в кавычки строку, чтобы встроенные специальные символы в Ваша строка не имеет нежелательных эффектов:

grep { /\Q$substr\Esomething_else/ } @array

Более того, если все, что вас волнует, - это значение, где-то , вы можете замкнуть накоротко, как только найдете совпадение:

use List::Util 'first';
if (first { $_ eq $new_href } @m_href_array) { ... }

или

use List::MoreUtils 'any';
if (any { $_ eq $new_href } @m_href_array) { ... }

Если вы собираетесь выполнять много поисков или ваш массив очень длинный, вы можете еще быстрее ускорить процесс, преобразовав массив в хеш, поэтому у вас будет O (1) поиск:

my %values_index;
@values_index{@array} = ();

if (exists $values_index{$element}) { ... }
4 голосов
/ 21 сентября 2010

Здесь вам не нужно регулярное выражение. Просто используйте eq:

grep { $_ eq $new_href } @m_href_array

Также рекомендуется использовать хэш вместо массива для более быстрой проверки:

my %allready_used_url;

if ( $self->{_local} eq "true" && ! exists $allready_used_url{ $new_href } ) {
    $allready_used_url{ $new_href } = 1; ## add url to hash
    push( @m_href_array, $new_href );
    push( @href_array, $new_href );
}
0 голосов
/ 22 сентября 2010

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

 use 5.010;

 if( $new_href ~~ @urls ) { ... }
0 голосов
/ 21 сентября 2010

Похоже, что значение $new_herf равно javascript:SearchGo(, которое при замене в проверке регулярных выражений выглядит следующим образом:

^javascript:SearchGo(?$

, что является ломаным регулярным выражением, поскольку не найдено ) для (

0 голосов
/ 21 сентября 2010

Что вы подразумеваете под ? в $new_href?? Предполагая, что в $new_href есть строка, ожидаете ли вы, что последняя буква строки будет необязательной? Парсер RE читает его не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...