How-to Guide 5 min read

Regex for Password Validation: Length, Digit and Symbol Rules

Build and test a password regex with lookaheads: minimum length, uppercase, digit and symbol rules, no spaces, plus the mistakes that let bad passwords through.

password regexregex for password validationpassword regex lookaheadregex at least one number and special characterjavascript password validation regex

The short answer

To require a minimum length plus at least one lowercase letter, one uppercase letter, one digit and one symbol, use one lookahead per rule followed by a length check:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,64}$

Each (?=...) checks one condition without consuming characters, and .{8,64} sets the length. Paste it into the Regex Tester with a few sample passwords to see exactly which ones match before you put it in your code.

How the pattern works, piece by piece

PartMeaning
^Start of the string
(?=.*[a-z])Somewhere ahead there is a lowercase letter
(?=.*[A-Z])Somewhere ahead there is an uppercase letter
(?=.*\d)Somewhere ahead there is a digit 0 to 9
(?=.*[^A-Za-z0-9])Somewhere ahead there is a character that is not a letter or digit
.{8,64}8 to 64 characters in total
$End of the string

A lookahead is a test, not a match. The engine stands at the start of the string, checks "is there a lowercase letter ahead?", returns to the start, checks the next rule, and so on. Only when every lookahead passes does it try to match the 8 to 64 characters. That is why you can add or remove rules independently: each rule is one self-contained (?=...) block.

Test it in the Regex Tester

  • Open the Regex Tester.
  • Paste the pattern into the box between the two slashes. Do not type the slashes yourself.
  • In the flags box, enter gm. The m flag makes ^ and $ match at the start and end of every line, so you can test many passwords at once, one per line.
  • In the test string box, enter samples like these, one per line:
    • Passw0rd!
    • password
    • PASSWORD1!
    • Abcdef1!
    • Ab1!
    • Pass word1!

    The tool highlights each matching line and lists every match with its position. With the pattern above, Passw0rd!, Abcdef1! and Pass word1! match. password fails (no uppercase, digit or symbol), PASSWORD1! fails (no lowercase) and Ab1! fails (too short).

    Notice that Pass word1! passed. The space counts as a "symbol" because it is not a letter or digit. If you do not want spaces, see the next section.

    When you move the pattern into a form, you normally test one password at a time, so drop the m flag and the g flag.

    Common variations

    No spaces allowed

    Replace the final . with \S (any non-whitespace character):

    ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9])\S{8,64}$

    Now Pass word1! fails and Passw0rd! still passes.

    Only certain symbols count

    If your rule says "one of these symbols: ! @ # $ % & *", list them in the lookahead instead of using "not a letter or digit":

    ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%&*]).{8,64}$

    Be careful: this does not stop people using other symbols elsewhere in the password. It only demands that at least one of the listed ones appears.

    Length only

    If you follow current guidance and check length rather than character mix, the regex is simply ^.{15,64}$. Change the numbers to match your policy.

    At least two digits

    Repeat the inner part: (?=(?:.*\d){2}) means "two digits somewhere ahead".

    Mistakes that let bad passwords through

    • Forgetting the anchors. Without ^ and $, .{8,64} can match any 8 to 64 characters inside a longer string, so a 200-character input still reports a match and slips past your maximum length. Always anchor password patterns.
    • Using a character whitelist instead of lookaheads. A pattern like ^[A-Za-z0-9!@#$%^&*]{8,}$ only limits which characters are allowed. password passes it, because it never requires a digit or uppercase letter.
    • Assuming "symbol" means ASCII punctuation. [^A-Za-z0-9] also matches spaces, emoji and letters such as ä or é. In testing, Pässw0rd! satisfies the symbol rule twice over. If that matters, list the allowed symbols explicitly.
    • Setting a low maximum length. Long passphrases are good passwords. A cap such as 16 or 20 characters blocks them. Allow at least 64.
    • Validating only in the browser. A regex in JavaScript stops honest mistakes, not attackers. Repeat the same check on the server.
    • Reporting only "invalid password". Users fix problems faster when you tell them which rule failed. Test each lookahead separately in code (for example "has a digit?") and show a message per rule.

    Should you force character rules at all?

    Composition rules are common, but they are no longer what security standards recommend. NIST's digital identity guidelines (SP 800-63B, revision 4, released in 2025) say verifiers shall not impose composition rules such as requiring a mix of character types. Instead they emphasise length (15 characters minimum when a password is the only factor), allowing long passwords of at least 64 characters, and checking new passwords against a blocklist of common or breached passwords.

    If you are free to choose your own policy, a length check plus a blocklist is stronger and friendlier than "one uppercase, one digit, one symbol". If a client, exam or legacy system requires composition rules, the lookahead pattern above is the cleanest way to implement them. Either way, a regex only checks the format. To see how guessable a password actually is, try the Password Strength Checker, and to generate one that passes any rule set, use the Password Generator.

    Where this regex syntax works

    The Regex Tester runs patterns with JavaScript's own regular expression engine, so what you see is what a browser or Node.js app will do. Lookaheads, \d, \S and character classes work the same way in Python, Java, PHP (PCRE) and .NET. In some configuration files and older tools, lookaheads are not supported, so test in the target system as well. For the basics of quantifiers, anchors and groups, see the Regex Beginners Guide.

    Frequently asked questions

    What is the regex for a password with at least one number and one special character?

    Use ^(?=.*\d)(?=.*[^A-Za-z0-9]).{8,64}$ and add (?=.*[a-z]) and (?=.*[A-Z]) if you also need lowercase and uppercase letters.

    Why do password regexes use lookaheads?

    Each lookahead checks one rule anywhere in the string without consuming characters, so several independent rules can be combined before the final length check.

    How do I stop spaces in a password regex?

    Replace the final .{8,64} with \S{8,64}, which allows any character except whitespace.

    Does NIST recommend password composition rules?

    No. NIST SP 800-63B revision 4 says verifiers shall not impose composition rules and instead stresses length, support for long passwords and blocklist checks.

    Try this tool on Lazyblink

    Put this guide into practice with our free online tool — no signup required.

    Open tool