Don't match [this]

After while of coding unless or !=, the logic starts getting unreadable. It's easy to communicate to someone "everything but the kitchen sink", but how does one say this with a PCRE? Say that with Zero Width Negative Lookahead Assertions (ZWNLA).

Zero Width Positive Lookahead Assertions

The traditional match, now with an impressive name and syntax sure to wow your codeworkers.

% perl -e '$animal = "cow"; print "$animal\n" if $animal =~ /(?=(cow))/;'

# or with some regex around the assertion
% perl -e '$animal = "cow"; print "$animal\n" if $animal =~ /^(?=(cow))/;'

Zero Width Negative Lookahead Assertions

The negation match - everything but...

% perl -e '$animal = "cow"; print "$animal\n" if $animal =~ /(?!(cow))/;'
# odd - still prints

% perl -e '$animal = "cow"; print "$animal\n" if $animal =~ /^(?!(cow))/;'
# works as expected - ZWNLA require _some_ _other_ regex around it to work

An example from history

#!/usr/bin/perl -w

my @disciples= qw(james peter john matthew mark judas bartholomew);

foreach my $d (@disciples) {
    printf "disciple -> $d\t";
    if ($d =~ /^(?!(judas))/) {    # The "^" is needed else the regex will not work.
        printf "\-neg assert (was there afterwards) \t$d matches\n";
    } else {
        printf " did not match (was a betrayer)\n";

Run the script and see how we can list out folks that were not there after the crucifixion.

% ./test
disciple -> james   -neg assert (was there afterwards)  james matches
disciple -> peter   -neg assert (was there afterwards)  peter matches
disciple -> john    -neg assert (was there afterwards)  john matches
disciple -> matthew -neg assert (was there afterwards)  matthew matches
disciple -> mark    -neg assert (was there afterwards)  mark matches
disciple -> judas    did not match (was a betrayer)
disciple -> bartholomew -neg assert (was there afterwards)  bartholomew matches


(?=regex) match this

(?!regex) don't match this - and need to put some regex around it to work.

Published on in