/^/
EasySecurity4 min read

Basic Password Regex

Validates a simple password policy: 6-20 alphanumeric characters containing at least one letter and one digit, with no special-character or mixed-case requirements.

#password#security#validation#authentication#forms

Regex Pattern

^(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9]{6,20}$

Pattern Breakdown

Hover over a token to see what it does.

^(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9]{6,20}$
TokenMeaning
^Anchors the checks to the start of the string
(?=.*[A-Za-z])Positive lookahead requiring at least one letter (upper or lower case) anywhere in the string
(?=.*\d)Positive lookahead requiring at least one digit anywhere in the string
[A-Za-z0-9]{6,20}The actual match: 6 to 20 characters, each a letter or digit
$Anchors the match to the end of the string

Detailed Explanation

What it does

This pattern enforces a lightweight password policy: the password must be 6-20 characters long, made up only of letters and digits, and contain at least one letter and one digit. Unlike a strong-password policy, it does not require mixed case or special characters.

Why it works

The two lookaheads independently confirm a letter and a digit exist somewhere in the string without consuming any characters, so both can be checked from the same starting position. The final `[A-Za-z0-9]{6,20}` then consumes and bounds the whole string, enforcing both the length limits and the letters-and-digits-only character whitelist.

Common use cases

  • Low-friction sign-up forms for internal tools or low-risk accounts where usability matters more than strict complexity
  • Quick prototype or MVP account systems before a full password policy is designed
  • Validating PINs or simple access codes that mix letters and numbers
  • Providing a gentler alternative to strict policies for products with a broad, non-technical user base

Edge cases

  • A password like 'abcdef' fails since it has no digit, even though it meets the length requirement
  • Special characters like '!' or '_' are rejected outright since the character class only allows letters and digits
  • A 20-character password is the longest accepted; longer input, even if otherwise valid, is rejected
  • Passwords like 'aaaaa1' pass despite being highly predictable, since this policy checks composition, not entropy

Limitations

  • Provides much weaker security guarantees than a strong-password policy with case, length, and symbol requirements
  • Does not check against common password dictionaries or breached-password lists
  • Does not measure actual entropy or predictability of the chosen password
  • Excludes legitimate special characters some users may want to include, since only letters and digits are allowed

Interactive Tester

Edit the pattern or text below — matching runs live in your browser.

abc123 Password1 Passw0rd

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass

Language Variants

Production-ready examples in 12 languages.

const basicPasswordPattern = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9]{6,20}$/;

function isBasicValidPassword(value) {
  return basicPasswordPattern.test(value);
}

console.log(isBasicValidPassword("abc123")); // true

Common Mistakes

Using this basic policy for high-value accounts (banking, admin) where stronger complexity is warranted

Fix: Reserve this lighter policy for low-risk contexts and use a stricter pattern like password-strong for sensitive accounts

Assuming Go's or Rust's standard regex engines support lookahead the same way JavaScript does

Fix: RE2-based engines (Go's regexp, Rust's regex crate) don't support lookahead; check letter and digit presence with separate simple regexes instead

Forgetting that spaces and special characters are rejected outright by the [A-Za-z0-9] whitelist

Fix: Widen the character class if you want to allow passphrases with spaces or symbols

Performance Notes

  • Two lightweight lookaheads plus a bounded final match keep this pattern fast even on longer passwords
  • Because lookaheads are zero-width, they don't interact with the final match's backtracking
  • The bounded {6,20} quantifier on a simple character class carries no catastrophic backtracking risk

Browser Compatibility

EngineSupportedNotes
ChromeYesLookahead assertions are supported in all modern JavaScript engines.
FirefoxYes
SafariYes
EdgeYes
Node.jsYes