Perl替换运算符可以匹配数组中的元素吗?

Rad*_*adz 8 perl

我有这样的数组

my @stopWords = ("and","this",....)
Run Code Online (Sandbox Code Playgroud)

我的文字在这个变量中

my $wholeText = "....and so this is...."
Run Code Online (Sandbox Code Playgroud)

我想匹配标量wholeText中我的stopWords数组的每个元素的每一个出现,并用空格替换它.

一种方法如下:

foreach my $stopW (@stopWords)
{
   $wholeText =~ s/$stopW/ /;
}
Run Code Online (Sandbox Code Playgroud)

这适用于并替换所有停用词的每次出现.我只是想知道,如果有更短的方法.

像这样:

$wholeText =~ s/@stopWords/ /;
Run Code Online (Sandbox Code Playgroud)

以上似乎不起作用.

Dav*_*man 7

虽然各种基于map/ for的解决方案都可以使用,但它们也会针对每个停用词分别对字符串进行正则表达式处理.虽然在给出的示例中这没什么大不了的,但随着目标文本和禁用词列表的增长,它可能会导致严重的性能问题.

乔纳森莱弗勒和罗伯特P在正确的轨道上提出了将所有停用词混合成一个正则表达式的建议,但是简单join的所有停用词变为单一的替换是一种粗略的方法,如果禁用词列表是长.

输入Regexp :: Assemble,它将为你构建一个更"智能"的正则表达式来同时处理所有匹配 - 我已经使用它来获得良好的效果,最多可以检查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;
Run Code Online (Sandbox Code Playgroud)

哪个输出:

\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.
Run Code Online (Sandbox Code Playgroud)


zou*_*oul 6

我最好的解决方案

$wholeText =~ s/$_//g for @stopWords;
Run Code Online (Sandbox Code Playgroud)

您可能希望使用某些\b和空格来锐化正则表达式.


Nik*_*ain -1

grep{$wholeText =~ s/\b$_\b/ /g}@stopWords;
Run Code Online (Sandbox Code Playgroud)

  • 这实际上是一种与“$wholeText =~ s/\b$_\b/ /g foreach @stopWords;”完全相同的混淆方式。不要那样做。 (2认同)