Используйте Regexp::Assemble, чтобы включить поиск в одном регулярном выражении. Таким образом, каждая строка должна быть отсканирована, только делая ее более эффективной для большого количества строк.
Regexp :: Assemble предпочтительнее делать это вручную. У этого есть полный API вещей, которые вы можете захотеть сделать с таким регулярным выражением, он может обрабатывать граничные случаи, и он может разумно скомпилировать в более эффективное регулярное выражение.
Например, эта программа производит (?^:\b(?:t(?:hree|wo)|one)\b)
, что приведет к меньшему обратному отклонению. Это становится ОЧЕНЬ важным, поскольку ваш список слов увеличивается по размеру. Последние версии Perl, около 5.14 и выше, сделают это для вас.
use strict;
use warnings;
use v5.10;
use Regexp::Assemble;
# Wrap each word in \b (word break) so only the full word is
# matched. 'one' will match 'money' but '\bone\b' won't.
my @words= qw(
\bone\b
\btwo\b
\bthree\b
);
# These lines simulate reading from a file.
my @lines = (
"won for the money\n",
"two for the show\n",
"three to get ready\n",
"now go cat go!\n"
);
# Assemble all the words into one regex.
my $ra = Regexp::Assemble->new;
$ra->add(@words);
for my $line (@lines) {
print $line if $line =~ $ra;
}
отметить также foreach
style loop to iterate over an array и использование statement modifier.
Наконец, я использовал \b
, чтобы гарантировать соответствие только фактических слов, а не подстрок, таких как money
.
[ 'list2re' из данных :: Munge] (https://metacpan.org/pod/Data::Munge#list2re-LIST) делает что-то очень похоже, но также обрабатывает несколько крайних случаев , – melpomene
+1 от OP. Мне нравится этот (он вроде показывает араканские пути perl, которые я ожидал). Но тот, у кого есть сборка, лучше подходит мне. Спасибо за ответ. – Terminality