Хотя различные решения, основанные на map
/ for
, будут работать , они также будут обрабатывать регулярные выражения вашей строки отдельно для каждого стоп-слова.Хотя в приведенном примере это не так уж и сложно, это может привести к серьезным проблемам с производительностью при увеличении целевого текста и списка стоп-слов.
Джонатан Леффлер и Роберт П. находятся на правильном пути, предлагая использовать все стоп-словавместе в одно регулярное выражение, но простой join
из всех стоп-слов в одном чередовании является грубым подходом и, опять же, становится неэффективным, если список стоп-слов длинный.
Enter Regexp ::Соберите , который создаст вам более «умное» регулярное выражение для обработки всех совпадений - я использовал его с хорошим эффектом со списками из 1700 или около того слов, с которыми нужно проверить:
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use Regexp::Assemble;
my @stopwords = qw( and the this that a an in to );
my $whole_text = <<EOT;
Fourscore and seven years ago our fathers brought forth
on this continent a new nation, conceived in liberty, and
dedicated to the proposition that all men are created equal.
EOT
my $ra = Regexp::Assemble->new(anchor_word_begin => 1, anchor_word_end => 1);
$ra->add(@stopwords);
say $ra->as_string;
say '---';
my $re = $ra->re;
$whole_text =~ s/$re//g;
say $whole_text;
Какие выходы:
\b(?:t(?:h(?:at|is|e)|o)|a(?:nd?)?|in)\b
---
Fourscore seven years ago our fathers brought forth
on continent new nation, conceived liberty,
dedicated proposition all men are created equal.