Один способ: сформировать шаблон, используя чередование ключей, и протестировать строки с ним
use warnings;
use strict;
use feature 'say';
my @strings = qw(pre-not pre1-pre2-text1-text2 pre3-text3 pre4-pre5-pre6-text4);
my %h = ( 'pre1-pre2' => 1, 'pre3' => 1, 'pre4-pre5-pre6' => 1 );
my $keys_re = join '|', map { quotemeta } keys %h;
foreach my $str (@strings) {
say $str if $str =~ /$keys_re/;
}
Это имеет квадратичную сложность, но чередование не будет проходить через все ключи и его C (регулярное выражение само).
Возможное улучшение (или необходимость!) Может заключаться в надлежащей сортировке ключей.Например, самый короткий первый
my $keys_re = join '|', map { quotemeta } sort { length $a <=> length $b } keys %h;
Это может помочь, если есть ключи с общими частями, но учтите, что это может быть нетривиальная настройка, которая может повлиять на правильность - и какая может потребоваться;Тщательно продумайте.
Чтобы также получить сам ключ, добавьте круглые скобки вокруг шаблона
foreach my $str (@strings) {
say "$str matched by key: $1" if $str =~ /($keys_re)/;
}
, где $1
содержит чередование, которое совпало и было получено, что является ключом.