I start with
(.)(.)\2\1
Now to invert I change it to
(?!(.)(.)\3\2)
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?
NB: I used ∗ as my asterisk to avoid bb-code.
^(?!.*(.)(.)\2\1)
You may also need to fill in the places where it could be anything. The above worked on abba for me.BTW a double space indent then formats as code on HN I think.
I went with:
^(?!.(.)(.)\2\1).$
with the thought that if I really wanted those matches I would want the whole strings.
Fun game!
^(?!.*(.)(.)\2\1).*$
With proper formatting hopefully. (?!....)
is a lookaround, so it matches 0 characters. So ^(?!....)$
will only match an empty string! (Think about it). Try ^(?!....$)
instead (the $ anchor inside the lookaround) > ^(?!(.)(.)\3\2)$
> But now it matches nothing.
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 :)