Many times I would match the exact opposite opposite of what I wanted. Is there a general rule for inverting regexps? ^ and ?! don't seem general purpose.
You need to pin the match to the start and end of the string with ^ and $ respectively otherwise the negation just matches an empty string or other irrelevant string.
As you say, the negation matches an empty string. So I put on anchors:
^(?!(.)(.)\3\2)$
But now it matches nothing. I'm not even sure what that regexp says. The entire string is a negation? Would anything match that regexp?
I see elsewhere on this page that the answer involves putting in an extra dummy character, putting that new negation-and-dummy-character in parens, and then requiring that, between the anchors, there be 0-or-more of negation-and-dummy-character.
^((?!(.)(.)\3\2).)∗$
Two questions:
1. Why are my backrefs still \3 and \2? I added another pair of parens. (I thought ?! might not count, but it counted in my second example above.
2. Why does abba no longer match? It has no matches to the negation-and-dummy character construct, which ∗ should match, right?
Things like (?!..) are called assertions. I like to think of assertions as patterns that match the space between two characters. So (?!a) means that it matches the space, where the next character is not 'a'.
So in this case, your regex matches an empty string (since it doesn't match any character at all between ^ and $, only spaces.)
> ^((?!(.)(.)\3\2).)∗$
> 1. Why are my backrefs still \3 and \2?
Well, you're referencing the second and third opening parenthesis.
> but it counted in my second example above
Maybe that's because your second example is wrong? I mean, I don't really know what you are trying to achieve in your second example.
By the way, my solution for abba is
^(?!.*(.)(.)\2\1)
I guess you'll will be able to figure out what this regex means by now :)