Hacker News new | past | comments | ask | show | jobs | submit login

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.


Just to follow my thought pattern.

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.


  >  ^(?!(.)(.)\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 :)


Remember

  (?!....) 
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)


  ^(?!.*(.)(.)\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.


Your approach scores higher, but it only matches the (imaginary) space before the "good" words.

I went with:

^(?!.(.)(.)\2\1).$

with the thought that if I really wanted those matches I would want the whole strings.

Fun game!


oops,

  ^(?!.*(.)(.)\2\1).*$
With proper formatting hopefully.


Yeah, I couldn't figure out how to invert the abba one (.)(.)\2\1 without help.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: