Code of the Day
BeginnerCore syntax

Character classes

Match any character from a defined set using bracket notation, ranges, negation, and the built-in shorthand classes like \d, \w, and \s.

Regular ExpressionsBeginner9 min read
By the end of this lesson you will be able to:
  • Write a character class that matches any character from a set
  • Use ranges like [a-z] and [0-9] in a class
  • Negate a class with [^…] to match anything outside the set
  • Apply the shorthand classes \d, \w, \s and their uppercase negations

A character class lets you say "match any one character from this group" without listing every possibility as alternation. Instead of /a|e|i|o|u/ to match a vowel you write /[aeiou]/.

Basic character class syntax

Wrap the allowed characters in square brackets:

/[aeiou]/.test("apple");     // true  — 'a' is in the class
/[aeiou]/.test("rhythm");    // false — no vowel in the string
/[aeiou]/g.exec("team");     // finds 'e', then 'a'

The class matches exactly one character, but that character can be any of the listed options. Order inside the brackets does not matter — [aeiou] and [uoiea] are identical.

Ranges

You can express a contiguous range with a hyphen - inside the brackets:

/[a-z]/       // any lowercase ASCII letter
/[A-Z]/       // any uppercase ASCII letter
/[0-9]/       // any digit character
/[a-zA-Z]/    // any letter, upper or lower case
/[a-zA-Z0-9]/ // any alphanumeric character

The hyphen is only special when it sits between two characters inside a class. At the start or end of a class it is treated as a literal hyphen:

/[-+]/.test("+");    // true — matches + or -
/[a-z-]/.test("-");  // true — matches letter or literal hyphen

Ranges are based on ASCII code points, so [A-z] is legal but probably wrong: it includes characters like [, \, ], ^, _, and ` that sit between uppercase and lowercase letters in the ASCII table. Use [A-Za-z] instead.

Negated classes

Put ^ immediately after the opening bracket to match any character except the listed ones:

/[^aeiou]/.test("b");   // true  — 'b' is not a vowel
/[^aeiou]/.test("a");   // false — 'a' is in the excluded set
/[^0-9]/.test("5");     // false — '5' is a digit
/[^0-9]/.test("x");     // true  — 'x' is not a digit

[^…] still matches exactly one character — it just rejects the ones you listed.

Shorthand classes

The most common character classes have single-character shorthands. You can use these inside or outside square brackets:

ShorthandMeaningEquivalent class
\dAny digit[0-9]
\DAny non-digit[^0-9]
\wWord character (letters, digits, underscore)[a-zA-Z0-9_]
\WNon-word character[^a-zA-Z0-9_]
\sWhitespace (space, tab, newline, etc.)[ \t\n\r\f\v]
\SNon-whitespace[^ \t\n\r\f\v]

The uppercase version is always the negation of the lowercase version.

/\d/.test("abc123");     // true — '1' is a digit
/\D/.test("abc123");     // true — 'a' is a non-digit
/\w/.test("hello_42");   // true — all word characters
/\s/.test("hello world");// true — the space is whitespace

You can combine shorthands inside a class bracket:

/[\d\s]/.test("3");      // true — matches digit or whitespace
/[\w-]/.test("my-key");  // true — matches word char or hyphen

The dot wildcard

The . metacharacter (outside a character class) matches any single character except a newline:

/h.t/.test("hat");       // true
/h.t/.test("hit");       // true
/h.t/.test("h\nt");      // false — newline not matched by .

The dot is a shorthand for "match almost anything" rather than a named character class, but it appears so often it belongs in this lesson. The s flag (dotall) makes . match newlines too — that is covered in the flags lesson.

Inside a character class, the dot . loses its special meaning and becomes a literal period: /[.]/ matches only a literal dot, not any character. Most metacharacters lose their special meaning inside […].

Putting it together

JavaScript — editable, runs in your browser

Quick reference table

PatternMatches
[abc]a, b, or c
[^abc]anything except a, b, c
[a-z]any lowercase ASCII letter
[A-Z]any uppercase ASCII letter
[0-9]any digit (same as \d)
[a-zA-Z0-9_]any word character (same as \w)
\ddigit [0-9]
\Dnon-digit
\wword character
\Wnon-word character
\swhitespace
\Snon-whitespace
.any character except newline

Where to go next

Next: quantifiers — controlling how many times a character class (or any atom) must match: +, *, ?, {n}, and the greedy-vs-lazy distinction.

Finished reading? Mark it complete to track your progress.

On this page