2

There are so many questions on regex-negation here on SO.

I am not sure I understand why people feel the need to negate a regex. Why not use something like grep -v that shows only the results that do not match the regex?


$ ls
april  august  december  february  january  july  june  march  may  november  october  september
$ ls | grep ber
december
november
october
september
$ ls | grep -v ber
april
august
february
january
july
june
march
may
Community
  • 1
  • 1
Lazer
  • 90,700
  • 113
  • 281
  • 364
  • 12
    Regexes are used for a lot more than just `grep`, you know... – David Z May 23 '10 at 06:46
  • 1
    There are so many questions on "regex negation" here because there is no such thing as a negative regex, and regex newbies tend to be surprised by this. – Tomalak May 23 '10 at 06:58
  • @Tomalak: There's negative look-aheads and such... and you can negate those `[sets]`. – mpen May 23 '10 at 07:04
  • 2
    +1 Don't know why this question was downvoted, seems like a clear question with a concrete answer. – Daniel Harms May 23 '10 at 07:15
  • @Mark: That does not affect my statement. A negative lookahead must *match* for the regex to succeed, it does not switch the regex into "match anything but" mode. Regexes must be constructed with matching, not excluding, in mind. While character classes (sets) can be negated, they are unsuitable to exclude words or phrases. – Tomalak May 23 '10 at 07:18
  • @Tomalak: Oh I didn't say you were wrong......was just pointing it out... :) – mpen May 23 '10 at 07:22
  • In a regex automaton you would toggle the accepting states to get the complement is this not possible with regex syntax? – Martin Smith May 23 '10 at 08:55

3 Answers3

9

Probably because grep isn't the only place that regexes are used? It works in this simple scenario... and actually in many others where you can just say "doesn't match this regex"... but... well, what if you need to negate only part of a regex? "Matches this, but doesn't match this" how would you do that? You can't just negate the whole thing.

mpen
  • 272,448
  • 266
  • 850
  • 1,236
2

You're right that there's no need to negate a whole regex, but certainly you see value in negating a subpattern within a larger pattern?

Here's a simple example: split a string into runs. In Java, this is simply a split on (?<=(.))(?!\1).

System.out.println(java.util.Arrays.toString(
    "aaaabbbccdeeefg".split("(?<=(.))(?!\\1)")
)); // prints "[aaaa, bbb, cc, d, eee, f, g]"

The regex is:

  • (?<=(.)) - lookbehind and capture a character into \1
  • (?!\1) - lookahead and negate a match on \1

Related questions

All of these questions uses negative assertions:

Community
  • 1
  • 1
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
0

One instance where I remember needing it, was in an Apache configuration. In Apache, there is a way to redirect to a different URI if the current request matches some PCRE regexp, but there is (or at least was, back when I needed it) no way to redirect if the current request does not match a regexp.

Thankfully, I was able to Google (actually, I'm not sure that Google existed already …) for a regexp-negation regexp. But it sure took me some time, and if StackOverflow had existed back then, it would have been much easier.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653