in reply to Blacklisting with a Regular Expression

/^(?!.*(?:evil|bad|wrong))/ seems to work for me. The key was the ^ at the begining. With that, it's forced to try from the begining. Otherwise, it keeps searching until it finds a place that doesn't have any of the blacklisted words (for instace, at the end of the string) and then succeeds.
#!/usr/bin/perl -l use strict; use warnings; my @blacklist = ('evil', 'bad', 'wrong'); #$a and $b are bad variable names due to sorting things my $aa = "this string contains no blacklisted tokens"; my $bb = "this string is evil and wrong"; # The regex should express the blacklist is such a way that # # it will match on any string which DOES NOT contain any of # # the tokens in the blacklist, and it will fail to match on # # any string which DOES contain tokens from the blacklist. # my $regex = qr/^(?!.*(?:evil|bad|wrong))/; if (($aa =~ m/$regex/) && !($bb =~ m/$regex/)) { print "Woohoo"; }

Replies are listed 'Best First'.
Re^2: Blacklisting with a Regular Expression
by BenjiSmith (Novice) on Aug 18, 2005 at 23:26 UTC
    /^(?!.*(?:evil|bad|wrong))/
    Bingo. This is the correct solution.

    I tried this one a little earlier (knowing why it wasn't working):
    /^.*(?!evil|bad|wrong)/
    ...but it never occurred to me to put the .* INSIDE the negative lookahead.

    <slaps forehead/>

    Thanks to the rest of you for helping, but most of you actually reversed the problem. The regex needed to return a match from the clean string, not from the string containing the blacklisted tokens.

    Thanks!!

    --Benji

      Just for the sake of completeness, here's an alternative:

      /^(?:(?!evil|bad|wrong).)*\z/

      Eimi's solution is much faster for the problem as given, but this approach gives more control - if your problem becomes any more complex in the future it's a useful trick to have available.

      Hugo