2013-05-24 4 views
4

키워드 목록과 차단 목록이 있습니다. 블랙리스트 항목이 포함 된 모든 키워드를 삭제하고 싶습니다. 이런 식으로 일을하는 순간 임에서 : 궁금은 문자열에 포함 된 배열 항목 중 하나입니다.

my @keywords = ('some good keyword', 'some other good keyword', 'some bad keyword'); 
my @blacklist = ('bad'); 

A: for my $keyword (@keywords) { 
    B: for my $bl (@blacklist) { 
     next A if $keyword =~ /$bl/i;  # omitting $keyword 
    } 
    # some keyword cleaning (for instance: erasing non a-zA-Z0-9 characters, etc) 
} 

순간에 나는 약 25 milion 키워드와 블랙리스트에 hundrets 단어의 몇 가지있다 렸기 때문에,이 작업을 수행 할 수있는 가장 빠른 방법이있다.

+0

을 '@ keywords'로 필터링 된 배열을 원하십니까? –

+0

새로운 배열 일 수 있습니다. – gib

답변

4

가장 간단한 옵션은, 하나의 정규 표현식으로 join 블랙리스트 항목에 grep입니다 정규식과 일치하지 않는 사람들을 위해 키워드 목록 :

#!/usr/bin/env perl  

use strict; 
use warnings; 
use 5.010; 

my @keywords = 
    ('some good keyword', 'some other good keyword', 'some bad keyword'); 
my @blacklist = ('bad'); 

my $re = join '|', @blacklist; 
my @good = grep { $_ !~ /$re/ } @keywords; 

say join "\n", @good; 

출력 :

some good keyword 
some other good keyword 
+1

고마워요! 50K 키워드를 사용하는 테스트의 경우 실행 시간이 34 초에서 0.6 초로 단축되었습니다. – gib

+1

https://metacpan.org/module/Regexp::Assemble - Regexp :: Assemble은 성능을 향상시킵니다. – Oesor

+1

설명 : Perl -MData :: Printer -MRegexp :: Assemble -E "내 $ ra = Regexp :: Assemble-> new(); 내 $ word (qw/apple asp 응용 프로그램은 applard aardvark snake /를 목표로 함) {$ ra-> add ($ word)} p ($ ra-> re); " (? : ire)? | ardvark) | 뱀)을 제공합니다. – Oesor

0

이 그것을 수행해야합니다

my @indices; 
for my $i (0..$#keywords) { 
    for my $bl (@blacklist) { 
    if ($keywords[$i] =~ $bl) { 
     push(@indices, $i); 
     last; 
    } 
    } 
} 
for my $i (@indices) { 
    @keywords = splice(@keywords, $i); 
} 
3

당신이 중첩 된 루프를 유지하려면 my @blacklist = (qr/bad/i) 도움이 될 수 있습니다 검색을 프리 D.

또는 my @blacklist = ('bad', 'awful', 'worst')에서 my $blacklist = qr/bad|awful|worst/;으로 변경 한 다음 내부 루프를 if ($keywords[$i] =~ $blacklist) ...으로 바꿉니다.