Master JavaScript regex character classes: square bracket syntax, negated classes, ranges [a-z], shorthand classes \\d \\w \\s, and real-world pattern examples with interview Q&A.
Character classes let you match any single character from a defined set. Instead of matching one specific character, you define a "menu" of acceptable characters using square brackets [...]. They are the building blocks of almost every regex pattern.
📊 Character Class Visual Reference
CHARACTER CLASS SYNTAX:
─────────────────────────────────────────────────
[abc] → match ONE of: a, b, or c
[^abc] → match ONE character that is NOT a, b, or c
[a-z] → match ONE lowercase letter (a through z)
[A-Z] → match ONE uppercase letter (A through Z)
[0-9] → match ONE digit (0 through 9)
[a-zA-Z] → match ONE letter (upper or lower case)
[a-zA-Z0-9_] → match ONE word character (same as \w)
SHORTHAND CLASSES:
\d = [0-9] digits
\D = [^0-9] non-digits
\w = [a-zA-Z0-9_] word characters
\W = [^a-zA-Z0-9_] non-word characters
\s = [ \t\n\r\f\v] whitespace
\S = [^ \t\n\r\f\v] non-whitespace
💻 Example 1 — Basic Character Classes
// [abc] — match any ONE of these characters
console.log(/[aeiou]/.test("hello")); // true — 'e' is a vowel
console.log(/[aeiou]/.test("gym")); // false — no vowels
console.log("hello world".match(/[aeiou]/g)); // all vowels
// [a-z] — range: any single lowercase letter
console.log(/[a-z]/.test("HELLO")); // false — all uppercase
console.log(/[a-z]/.test("Hello")); // true — 'e','l','l','o' match
console.log(/[a-z]/i.test("HELLO")); // true — i flag makes [a-z] case-insensitive
// [0-9] — any digit
console.log(/[0-9]/.test("Room 42")); // true
console.log(/[0-9]/.test("none")); // false
true
false
[ 'e', 'o', 'o' ]
false
true
true
true
false
💻 Example 2 — Negated Classes [^...]
// [^...] — match any character NOT in the set
const text = "Hello, World! 123";
// Remove all non-letters (keep only letters)
console.log(text.replace(/[^a-zA-Z]/g, ""));
// Remove all non-digits (keep only digits)
console.log(text.replace(/[^0-9]/g, ""));
// Remove all non-alphanumeric characters
console.log(text.replace(/[^a-zA-Z0-9]/g, ""));
// Test: no special characters
console.log(/[^a-zA-Z0-9\s]/.test("Hello World")); // false — no special chars
console.log(/[^a-zA-Z0-9\s]/.test("Hello!")); // true — ! is special
HelloWorld
123
HelloWorld123
false
true
💻 Example 3 — Combined Ranges and Classes
// Hexadecimal digits: 0-9 and a-f
const isHex = str => /^[0-9a-fA-F]+$/.test(str);
console.log(isHex("FF00AA")); // true
console.log(isHex("ZZZZ")); // false
console.log(isHex("1a2b3c")); // true
// Valid variable names: start with letter/underscore, then word chars
const isValidVar = name => /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name);
console.log(isValidVar("myVar")); // true
console.log(isValidVar("_private")); // true
console.log(isValidVar("123abc")); // false — starts with digit
console.log(isValidVar("my-var")); // false — hyphen not allowed
// Indian phone: starts with 6, 7, 8, or 9
const isIndianPhone = n => /^[6-9]\d{9}$/.test(n);
console.log(isIndianPhone("9876543210")); // true
console.log(isIndianPhone("1234567890")); // false — starts with 1
true
false
true
true
true
false
false
true
false
💻 Example 4 — Shorthand vs Explicit Classes
const sample = "Hello, Riya! Phone: 9876543210. Score: 95.5%";
// Shorthand \d — digits (same as [0-9])
console.log(sample.match(/\d+/g));
// Shorthand \w — word characters [a-zA-Z0-9_]
console.log(sample.match(/\w+/g));
// Shorthand \s — whitespace
console.log(sample.split(/\s+/).length); // word count
// \D — non-digits (extract letters and symbols)
console.log("abc123def456".replace(/\D/g, "")); // keep only digits
// \W — non-word chars
console.log("Hello, World!".replace(/\W/g, " ")); // replace non-word with space
[ '9876543210', '95', '5' ]
[ 'Hello', 'Riya', 'Phone', '9876543210', 'Score', '95', '5' ]
7
123456
Hello World
💻 Example 5 — Character Classes Inside Complex Patterns
// Password strength check: at least one uppercase, lowercase, digit
function checkPassword(pwd) {
const hasUpper = /[A-Z]/.test(pwd);
const hasLower = /[a-z]/.test(pwd);
const hasDigit = /[0-9]/.test(pwd);
const hasSpecial = /[!@#$%^&*]/.test(pwd);
const isLong = pwd.length >= 8;
const strength = [hasUpper, hasLower, hasDigit, hasSpecial, isLong]
.filter(Boolean).length;
const levels = ["", "Very Weak", "Weak", "Fair", "Strong", "Very Strong"];
return `${levels[strength]} (${strength}/5)`;
}
console.log(checkPassword("password")); // only lower
console.log(checkPassword("Password1")); // upper + lower + digit + length
console.log(checkPassword("P@ssw0rd!")); // all criteria
Weak (2/5)
Strong (4/5)
Very Strong (5/5)
📋 Character Class Quick Reference
| Class | Meaning | Equivalent |
|---|
[abc] | a, b, or c | — |
[^abc] | NOT a, b, or c | — |
[a-z] | Any lowercase letter | — |
[A-Z] | Any uppercase letter | — |
[0-9] | Any digit | \d |
[a-zA-Z0-9_] | Word character | \w |
[ \t\n\r] | Whitespace | \s |
[^0-9] | Not a digit | \D |
[^a-zA-Z0-9_] | Not a word char | \W |
⚠️ Common Mistakes
❌ Mistake 1 — Hyphen Not at Start or End (Treated as Range)
// BAD — hyphen in middle treated as a range!
const bad = /[a-z-A-Z]/; // means a-z, hyphen, A-Z (hyphen here is literal)
// To include literal hyphen, put it at start or end:
const good = /[-a-zA-Z]/; // or /[a-zA-Z-]/
❌ Mistake 2 — Dot Inside [] Is Literal
// OUTSIDE [], . = any character
console.log(/./.test("x")); // true
// INSIDE [], . = literal dot
console.log(/[.]/.test("x")); // false — only matches "."
console.log(/[.]/.test(".")); // true
❌ Mistake 3 — Using [...] When You Need (...)
// [js] matches 'j' OR 's' — not the string "js"!
console.log(/[js]/.test("js")); // true (but for wrong reason — matches 'j' or 's')
console.log(/[js]/.test("x")); // false
// Use (js) or just /js/ for the literal string
console.log(/^[js]$/.test("js")); // false — [js] matches ONE character
🎯 Key Takeaways
[abc] matches any one character from the set[^abc] matches any one character NOT in the set- Ranges:
[a-z], [A-Z], [0-9] — use hyphen between start and end - Shorthand classes:
\d, \w, \s and their negations \D, \W, \S - Inside
[], most special characters lose their meaning (. is literal dot) - Hyphen
- inside [] must be at start or end to be treated as a literal hyphen
❓ Interview Questions
Q1. What is a character class in regex? > A character class [...] matches any single character from the set inside the brackets. [aeiou] matches any one vowel. [a-z] matches any lowercase letter. The key point: it always matches exactly ONE character.
Q2. What does [^abc] mean? > The caret ^ inside brackets negates the class — it matches any single character that is NOT in the set. [^0-9] matches any non-digit character.
Q3. What is the difference between . and [.]? > Outside brackets, . matches any character except newline. Inside brackets [.], the dot loses its special meaning and matches a literal dot character only.
Q4. How is \d different from [0-9]? > For ASCII text they are equivalent. However, \d with the u flag in Unicode mode can match digits from other scripts (Arabic numerals, etc.), while [0-9] strictly matches only the digits 0-9.
Q5. How do you include a literal hyphen in a character class? > Put it at the beginning [-abc] or end [abc-] of the class. In the middle, a hyphen defines a range — [a-c] means a, b, or c. [-] or [a\-z] (escaped) also works.
Q6. Can you combine ranges and individual characters in one class? > Yes — [a-zA-Z0-9_] combines three ranges and one character. You can mix freely: [a-f0-9!@#] matches hex digits plus three symbols.
Q7. What does \w match? > \w is shorthand for [a-zA-Z0-9_] — letters (upper and lower), digits, and underscore. It does NOT match spaces, hyphens, or other special characters.
Q8. How would you match any character that is NOT a whitespace? > Use \S (capital S) — shorthand for [^\s]. Or explicitly: [^ \t\n\r\f\v]. Useful for extracting words from text.