Regex match anything except specific characters
The negated character class [^...] is the right tool — clearer than lazy quantifiers, faster than alternation.
The short answer
Use a negated character class — square brackets with a caret at the start:
[^abc] match any single character except a, b, or c
[^"] match any character except a double quote
[^\d] match any non-digit character (same as \D)
[^A-Z] match anything except uppercase letters
To match multiple characters, add a quantifier: [^"]*, [^abc]+, etc.
How negation works
Inside [...], a caret ^ at the very beginning means "match any character that is NOT one of these." Without the caret, it matches "any character that IS one of these."
[abc] match a, b, or c
[^abc] match anything except a, b, c
If the caret isn't the first character, it's literal: [a^b] matches a, ^, or b.
Common use cases
Content between delimiters (the right way)
"[^"]*" content between double quotes
\[[^\]]*\] content between square brackets
<[^>]+> HTML tag with attributes
These are faster and clearer than the lazy alternatives ".*?", \[.*?\], <.+?>.
Words without specific characters
[a-zA-Z]+ only letters
[^aeiouAEIOU]+ only consonants (well, no vowels)
[a-zA-Z][a-zA-Z0-9_]* identifier (letter then letters/digits/underscores)
Lines not starting with a comment
^[^#] line doesn't start with #
^[^#].* match the whole line if it doesn't start with #
^(?!#).*$ same idea with negative lookahead
Shorthand negations
Several built-in classes are already negations of common groups:
| Shorthand | Equivalent | Meaning |
|---|---|---|
\D | [^0-9] | non-digit |
\W | [^A-Za-z0-9_] | non-word |
\S | [^\s] | non-whitespace |
Excluding multiple things
Combine literal characters, ranges, and shorthand classes inside the negation:
[^\d\s.,!?] not a digit, whitespace, or punctuation
[^a-zA-Z0-9] not alphanumeric
[^"'] not a quote (either kind)
[^<>] not an angle bracket
Excluding newlines
. already excludes newlines by default. So . and [^\n] are similar — but watch the differences:
. any char except \n (and \r in some flavors)
[^\n] any char except \n only
For most use cases . is fine. Use [^\n] when you specifically want to allow \r (Windows line endings) but not \n.
Negative lookarounds for "not preceded by"
Character classes negate one character at a time. For "not preceded by X" or "not followed by X", use lookarounds:
(?<!@)word match "word" if NOT preceded by @
word(?!ing) match "word" if NOT followed by "ing"
Combining negation with other constraints
You can negate one class and intersect with another using lookarounds:
(?=[^aeiou])[a-z] a lowercase letter that's not a vowel
Or, in flavors with class intersection (Java, ES2024 with /v flag):
[a-z&&[^aeiou]] lowercase consonants (Java)
[[a-z]--[aeiou]] same idea (ES2024 /v)
Common mistakes
Putting the caret in the wrong place
[a^bc] matches a, ^, b, or c — caret is literal!
[^abc] matches anything except a, b, c
The negation caret MUST be the first character inside the brackets.
Forgetting that ] needs escaping
Inside [...], a literal ] usually needs escaping (or being the first character right after the opening bracket / caret):
[]a-z] matches ] or lowercase letter — ] as first char is literal
[\]a-z] safer — escape it explicitly
The takeaway
The negated character class [^...] is one of the most useful constructs in regex. Use it for:
- Content between delimiters (much cleaner than lazy)
- "Anything except this single character or set"
- Excluding specific characters from a broader pattern
For "not preceded by" or "not followed by" — patterns about position rather than a single character — use negative lookarounds instead.
Related reading
Try this pattern in the explainer
Paste any regex into the live explainer and see what each token means, with example matches in real time.
Open the regex explainer →