Username Regex
Validates that a username is 3 to 16 characters long and contains only letters, digits, underscores, or hyphens.
Practice this Regex Pattern
Put your regex skills to the test! Try writing this pattern in our interactive challenges workspace.
Start Challenge →Regex Pattern
^[a-zA-Z0-9_-]{3,16}$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ^ | Anchors the match to the start of the string |
| [a-zA-Z0-9_-] | Character class allowing letters, digits, underscores, and hyphens |
| a-z | Lowercase letters within the character class |
| A-Z | Uppercase letters within the character class |
| 0-9 | Digits within the character class |
| _- | Underscore and literal hyphen (hyphen placed last so it isn't read as a range) |
| {3,16} | Quantifier requiring between 3 and 16 characters total |
| $ | Anchors the match to the end of the string |
Detailed Explanation
What it does
This pattern checks that an entire string is a valid username: only letters, digits, underscores, and hyphens are allowed, and the total length must fall between 3 and 16 characters. Any input containing spaces, punctuation, or an out-of-range length is rejected.
Why it works
The character class [a-zA-Z0-9_-] enumerates every acceptable character in one set, so a single quantified class can validate the whole body of the username. The {3,16} quantifier enforces the length constraint directly inside the character class repetition, and the ^ and $ anchors force the class to consume the entire input rather than just a portion of it.
Common use cases
- Validating sign-up form usernames before submitting to a backend
- Enforcing consistent handle formatting across a platform (chat apps, forums, games)
- Sanitizing usernames used in URLs or file paths (e.g. profile.com/username)
- Client-side input masking to give instant feedback while typing
Edge cases
- Usernames that are purely numeric, like 12345, are allowed unless additional rules are added
- Leading or trailing hyphens/underscores (e.g. _user_) are technically valid under this pattern
- Exactly 3 or exactly 16 characters are valid because the quantifier bounds are inclusive
- Unicode letters (e.g. accented characters or non-Latin scripts) are rejected since only a-z/A-Z are allowed
Limitations
- Does not prevent reserved words (admin, root) or profanity — that requires a separate blocklist check
- Does not enforce that a username starts with a letter, which some systems require
- No support for internationalized usernames without extending the character class with Unicode ranges
Interactive Tester
Edit the pattern or text below — matching runs live in your browser.
Test Cases
Editable — add your own inputs to see if they pass.
| Input | Expected | Result | |
|---|---|---|---|
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass |
Language Variants
Production-ready examples in 12 languages.
const usernameRegex = /^[a-zA-Z0-9_-]{3,16}$/;
console.log(usernameRegex.test('john_doe')); // trueCommon Mistakes
Forgetting the length quantifier and only checking allowed characters, letting a 1-character or 200-character string through
Fix: Always bound the length with a quantifier like {3,16} rather than validating characters alone
Placing the hyphen in the middle of the character class (e.g. [a-z0-9-_]) where it can accidentally form an unintended range
Fix: Put the hyphen first or last inside the character class, e.g. [a-zA-Z0-9_-], so it's always read literally
Using this pattern to also guarantee uniqueness or reserved-word exclusion
Fix: Combine the regex with a database uniqueness check and a blocklist for reserved names
Performance Notes
- A single bounded character class with {3,16} is O(n) and has no ambiguous repetition, so there is no catastrophic backtracking risk
- Anchoring with ^ and $ lets the engine reject over-length strings quickly without scanning the whole input
- Because the class has no overlapping alternatives, this pattern is safe to run on untrusted user input at scale
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |
Work with this pattern
Take this expression further — test it against your own data, adapt it in the builder, or read up on the syntax behind it.
Regex Tester
Test a regular expression against sample text and see every match highlighted live.
Regex Generator
Build a pattern by clicking blocks — no syntax memorisation required.
Regular Expressions Guide
What regex is, how the syntax works, and the mistakes that trip people up.
Regex Cheat Sheet
Every token, quantifier, and assertion on one printable page.
Python Regex Guide
The re module end to end — search, match, findall, groups, and substitution.
Regex Pattern Library
100+ ready-to-use patterns for email, URLs, dates, IPs, and more.