Regex tester · Guide

Regex Match But Exclude: Negative Lookahead and Non-Capturing Groups

"Match but exclude" means three different things depending on what you are excluding: characters, whole words, or parts of the match you do not want captured. Each has its own construct.

Excluding characters

A negated character class excludes specific characters. This is the simplest case and the fastest:

Regex
[^0-9]+        # anything that is not a digit
[^"]*          # anything up to the next quote
[^\s,]+        # a field: no whitespace, no comma

A common misunderstanding: [^abc] excludes the three characters individually, not the string "abc". To exclude a sequence you need a lookahead.

Excluding words with lookahead

A negative lookahead (?!...) asserts that something does not follow, without consuming input:

Regex
^(?!admin).*$          # any line not starting with "admin"
^(?!.*password).*$     # any line not containing "password" anywhere
\b(?!test)\w+\b        # words that do not start with "test"

The .* inside the second one is what makes it "anywhere" rather than "at this position" — a distinction that catches people out. Both patterns need anchoring to mean what they look like they mean.

Matching without capturing

A non-capturing group (?:...) groups for alternation or quantifiers without allocating a capture slot:

Regex
(?:https?|ftp)://(\S+)     # group 1 is the host, protocol not captured
(?:\d{3}-){2}\d{4}         # repeat without capturing each repetition

Beyond keeping group numbers meaningful, it avoids storing text you will never read. A good habit is to make every group non-capturing by default and promote it only when you extract the value.

Lookbehind for trailing context

(?<!...) excludes based on what precedes: (?<!un)happy matches "happy" but not "unhappy". Lookbehind support varies — JavaScript has it since ES2018, and PCRE requires it to be fixed-length.

Lookarounds are zero-width, so they never appear in the match. That is exactly why they are useful for context conditions and useless when you actually want the surrounding text.

Frequently asked questions

Does [^abc] exclude the word "abc"?

No, it excludes the three characters individually. Use a negative lookahead for a sequence.

How do I match lines not containing a word?

Anchor a negative lookahead with .* inside it: ^(?!.*word).*$

What is the difference between (?:...) and (?!...)?

(?:...) groups without capturing; (?!...) asserts that something does not follow and consumes nothing.

Ready to try it?

Open the free browser-based Regex tester and apply what you just read — no sign-up, runs locally.

Open the Regex tester tool