是的,我想你在那里做的事情非常缓慢,尽管有几个原因。我认为你需要处理你的停用词正则表达式在你从你的语料库中建立你的十亿个单词的字符串。
我不知道 .regex 文件是什么,但我假设它包含一个合法的 Perl 正则表达式,您可以使用以下内容进行编译:
$stopword_string = `cat foo.regex`;
$stopword_rx = qr/$stopword_string/;
这可能假定开头有一个(?x)。
但如果您的停用词文件是行列表,您将需要执行更多类似的操作:
chomp(@stopwords = `cat foo.regex`);
# if each stopword is an independent regex:
$stopword_string = join "|" => @stopwords;
# else if each stopword is a literal
$stopword_string = join "|" => map {quotemeta} @stopwords;
# now compile it (maybe add some qr//OPTS)
$stopword_rx = qr/\b(?:$stopword_string)\b/;
警告
非常小心\b:如果第一个单词中的第一个字符和最后一个单词中的最后一个字符是字母数字(a \w 字符)。否则,它将断言您可能不是故意的。如果有可能,您将需要更具体。前导 \b 需要变为 (?:(?<=\A)|(?<=\s)),而尾随 \b 需要变为 (?=\s|\z)。这是大多数人认为 \b 的意思,但事实并非如此。
完成此操作后,您应该在阅读语料库时将停用词正则表达式应用于语料库。最好的方法是不首先将内容放入您的字符串你只需要稍后取出。
所以不要这样做
$corpus_text = `cat some-giant-file`;
$corpus_text =~ s/$stopword_rx//g;
改为
my $corpus_path = "/some/path/goes/here";
open(my $corpus_fh, "< :encoding(UTF-8)", $corpus_path)
|| die "$0: couldn't open $corpus_path: $!";
my $corpus_text = q##;
while (<$corpus_fh>) {
chomp; # or not
$corpus_text .= $_ unless /$stopword_rx/;
}
close($corpus_fh)
|| die "$0: couldn't close $corpus_path: $!";
这比把东西放在那里要快得多,然后你必须再次清除。
我使用上面的cat 只是一个捷径。我不希望你真正调用一个程序,尤其是cat,只是为了读入一个未处理且不受干扰的文件。 ☺