簡體   English   中英

Perl替換運算符可以匹配數組中的元素嗎?

[英]Can Perl substitution operator match an element in an array?

我有這樣的數組

my @stopWords = ("and","this",....)

我的文字在這個變量中

my $wholeText = "....and so this is...."

我想匹配標量wholeText中我的stopWords數組的每個元素的每一個出現,並用空格替換它。

一種方法如下:

foreach my $stopW (@stopWords)
{
   $wholeText =~ s/$stopW/ /;
}

這適用於並替換所有停用詞的每次出現。 我只是想知道,如果有更短的方法。

像這樣:

$wholeText =~ s/@stopWords/ /;

以上似乎不起作用。

雖然各種基於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;

哪個輸出:

\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.

我最好的解決方案

$wholeText =~ s/$_//g for @stopWords;

您可能希望使用一些\\b和空格來銳化正則表達式。

關於什么:

my $qrstring = '\b(' . (join '|', @stopWords) . ')\b';
my $qr = qr/$qrstring/;
$wholeText =~ s/$qr/ /g;

連接所有單詞以形成' \\b(and|the|it|...)\\b '; 連接周圍的括號是必要的,以給它一個列表上下文; 如果沒有它們,你最終會計算出單詞的數量)。 ' \\b '元字符標記單詞邊界,因此阻止您將'千'變為'thous'。 將其轉換為帶引號的正則表達式; 將其全局應用於主題字符串(以便在單個操作中刪除所有出現的所有停用詞)。

您也可以不使用變量' $qr ':

my $qrstring = '\b(' . (join '|', @stopWords) . ')\b';
$wholeText =~ s/$qrstring/ /g;

我認為我不想維護任何沒有變量' $qrstring '的人的代碼; 它可能已經完成,但我不認為它會非常易讀。

我的偏執版:

$wholeText =~ s/\b\Q$_\E\b/ /gi for @stopWords;

使用\\b來匹配單詞邊界,並使用\\Q..\\E以防萬一你的任何一個停用詞包含可能被正則表達式引擎解釋為“特殊”的字符。

您可以考慮使用正則表達式連接來創建單個正則表達式。

my $regex_str = join '|', map { quotemeta } @stopwords;
$string =~ /$regex_str/ /g;

請注意, quotemeta部分只是確保正確轉義任何正則表達式字符。

grep{$wholeText =~ s/\b$_\b/ /g}@stopWords;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM