116

I have a regex, for example (ma|(t){1}). It matches ma and t and doesn't match bla.

I want to negate the regex, thus it must match bla and not ma and t, by adding something to this regex. I know I can write bla, the actual regex is however more complex.

Griffin
  • 2,328
  • 6
  • 46
  • 79
IAdapter
  • 59,319
  • 71
  • 171
  • 240
  • 6
    As an aside, `{1}` is completely useless. (If you do think it provides some value, why don't you write `((m{1}a{1}){1}|(t){1}){1}`?) – tripleee Jun 27 '16 at 10:26

4 Answers4

115

Use negative lookaround: (?!pattern)

Positive lookarounds can be used to assert that a pattern matches. Negative lookarounds is the opposite: it's used to assert that a pattern DOES NOT match. Some flavor supports assertions; some puts limitations on lookbehind, etc.

Links to regular-expressions.info

See also

More examples

These are attempts to come up with regex solutions to toy problems as exercises; they should be educational if you're trying to learn the various ways you can use lookarounds (nesting them, using them to capture, etc):

Community
  • 1
  • 1
polygenelubricants
  • 364,035
  • 124
  • 554
  • 617
61

Assuming you only want to disallow strings that match the regex completely (i.e., mmbla is okay, but mm isn't), this is what you want:

^(?!(?:m{2}|t)$).*$

(?!(?:m{2}|t)$) is a negative lookahead; it says "starting from the current position, the next few characters are not mm or t, followed by the end of the string." The start anchor (^) at the beginning ensures that the lookahead is applied at the beginning of the string. If that succeeds, the .* goes ahead and consumes the string.

FYI, if you're using Java's matches() method, you don't really need the the ^ and the final $, but they don't do any harm. The $ inside the lookahead is required, though.

Alan Moore
  • 71,299
  • 12
  • 93
  • 154
  • 3
    Most helpful part of this answer is that you have to add `.*` to the end of your regex, otherwise it will reject every string. – Rav Mar 21 '18 at 13:08
  • 2
    The `$` *inside* the negative lookahead, AND the `.*` at the end are both critical bits. As always with REs, a strong set of unit tests is absolutely critical to getting it right. This answer is 100% correct. – Tom Dibble Aug 07 '18 at 19:30
1
\b(?=\w)(?!(ma|(t){1}))\b(\w*)

this is for the given regex.
the \b is to find word boundary.
the positive look ahead (?=\w) is here to avoid spaces.
the negative look ahead over the original regex is to prevent matches of it.
and finally the (\w*) is to catch all the words that are left.
the group that will hold the words is group 3.
the simple (?!pattern) will not work as any sub-string will match
the simple ^(?!(?:m{2}|t)$).*$ will not work as it's granularity is full lines

Ofer Skulsky
  • 612
  • 4
  • 8
0

Apply this if you use laravel.

Laravel has a not_regex where field under validation must not match the given regular expression; uses the PHP preg_match function internally.

'email' => 'not_regex:/^.+$/i'
DAVID AJAYI
  • 1,452
  • 17
  • 13