Patrick Schmitter
Patrick Schmitter

Reputation: 11

RegEx - Find everything that does not contain a pattern

I got this regex code:

((\w)(\w)\3\2)

It matches everything that contains something like anna, otto, xyyx ...

But I want to match everything that does NOT contain such a pattern. How can i do that?

Upvotes: 1

Views: 916

Answers (2)

Vorsprung
Vorsprung

Reputation: 34307

Initially I thought this kind of does what you are asking. But for the reasons raised by @WiktorStribiżew below it does not work. In particular test strings such as AAAB and ABBC are supposed to match the below but do not

^((\w)(\w)(?!\3)(?!\2))

My second thought is to use

^((\w)(\w)(?!\3\2))

And this does seem to work.

New test program. This generates all possible strings from AAAA to ZZZZ. Then a non regexp check is used to test if each string should match or not. Finally, each string is checked for compliance against both the positive

$findrepeats, ^((\w)(\w)(\3)(\2)) matches abba

and the negative

$repeatnomatch ^((\w)(\w)(?!\3)(?!\2)) matches ab[not b][not a]

use strict;
use warnings;

my @fourchar=('AAAA'..'ZZZZ'); 

my @norepeats=();

my @hasrepeats=();

for my $pattern ('AAAA' .. 'ZZZZ') {
  if (checkstring($pattern)) {
    push @hasrepeats, $pattern;
    } else {
    push @norepeats, $pattern;
    }
}

print scalar @hasrepeats, " strings with repeated abba\n";
print scalar @norepeats, " strings with ab[not b][not a]\n";



my $findsrepeats=qr/^((\w)(\w)(\3)(\2))/;
my $repeatnomatch=qr/^((\w)(\w)(?!\3\2))/;

for my $example (@hasrepeats) {
  die $example if (not($example=~$findsrepeats));
  die $example if ($example=~$repeatnomatch);
}

for my $example (@norepeats) {
  die $example if (not($example=~$repeatnomatch));
  die $example if ($example=~$findsrepeats);
}

print "pass\n";

sub checkstring {
  my $s=shift;
  my @element=split(//,$s);
  return ($element[0] eq $element[3]  && 
          $element[1] eq $element[2]);
}

Running the above perl program should produce this output

$ perl nr3.pl 
676 strings with repeated abba
456300 strings with ab[not b][not a]
pass

Upvotes: 0

cromod
cromod

Reputation: 1799

This issue has already been raised on this SO post. You should try this :

^((?!(\w)(\w)\3\2).)*$

Upvotes: 1

Related Questions