PatternRegex

Enforce a strong password policy

One lookahead per rule: a lowercase, an uppercase, a digit and a symbol, minimum 8 characters — and why lookaheads are the right tool for the job.

Last updated

Pattern
(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}
Open in Regex Tester & Builder

Matches

  • Tr0ub4dor&3
  • correct-Horse-7!

Doesn’t match

  • alllowercase1!
  • NOLOWER1!
  • Short1!

Why it’s written this way

Each (?=…) is a lookahead: it scans ahead for one required character class without consuming anything, then hands control back to the start. Four independent rules become four independent lookaheads — add or drop a rule without rewriting the rest.

Only the final .{8,} actually consumes characters, which is where the length rule lives. When validating a whole input field, anchor it as ^…$ so a strong substring inside a weak password cannot pass.

Edge cases to know

  • The symbol rule [^\w\s] means "not alphanumeric, not whitespace" — spaces inside a passphrase pass the length rule but do not count as the symbol.
  • Composition rules are a floor, not a strength meter: Password1! passes. Pair it with a length slider or a breach check for real strength.
  • NIST guidance now favours length over forced composition — this pattern is for when policy demands composition anyway.

Related in Patterns