The SyntaxError: Invalid regular expression: ...: Range out of order in character class is a common error that occurs when a regular expression is constructed with a malformed range inside a character set ([...]). It almost always involves a misplaced hyphen (-).
This guide will explain what a "range out of order" means, the common mistakes that cause this error, and the simple, correct ways to include a literal hyphen in your character set.
The Core Problem: Ranges in Character Classes
In a regular expression, a character set [...] is used to match any single character from a list. A hyphen (-) inside a character set has a special meaning: it is used to define a range of characters.
[a-z]: Matches any lowercase letter from 'a' to 'z'.[0-9]: Matches any digit from '0' to '9'.[A-C]: Matches 'A', 'B', or 'C'.
A range is "in order" if the character on the left comes before the character on the right in the character encoding table (like ASCII or Unicode). [a-z] is valid, but [z-a] is a "range out of order."
The Cause of the Error: A Misplaced Hyphen
The error occurs when the regex engine tries to interpret a hyphen as a range, but the characters on either side of it do not form a valid, ordered range.
For example, imagine you want to match lowercase letters, uppercase letters, or a hyphen. A common mistake is to place the hyphen in the middle.
// Problem: The hyphen between 'a-z' and 'A-Z' is ambiguous.
const text = 'hello-world';
const regex = /[a-z-A-Z]/; // ⛔️ SyntaxError: Invalid regular expression: /[a-z-A-Z]/: Range out of order in character class
console.log(regex.test(text));The Solutions
To include a literal hyphen in your character set, you must place it in a position where it cannot be misinterpreted as part of a range.
Place the Hyphen at the Beginning or End (Recommended)
This is the cleanest and most readable solution. When a hyphen is the very first or very last character in a character set, it loses its special meaning and is treated as a literal character.
const text = 'hello-world';
// ✅ Solution 1: Place the hyphen at the beginning.
const regex1 = /[-a-zA-Z]/;
console.log(regex1.test(text)); // Output: true
// ✅ Solution 2: Place the hyphen at the end.
const regex2 = /[a-zA-Z-]/;
console.log(regex2.test(text)); // Output: trueEscape the Hyphen with a Backslash
You can also treat the hyphen as a literal character by "escaping" it with a backslash (\).
const text = 'hello-world';
// ✅ Solution 3: Escape the hyphen.
const regex = /[a-z\-A-Z]/;
console.log(regex.test(text)); // Output: truePractical Example: Matching a String with Hyphens
Let's create a regex to validate a simple product ID format, which should only contain uppercase letters, numbers, and hyphens.
function isValidProductId(id) {
// The regex matches a string that contains one or more (+)
// characters that are either uppercase letters (A-Z),
// numbers (0-9), or a hyphen (-).
// The ^ and $ anchors ensure the ENTIRE string must match this pattern.
const regex = /^[A-Z0-9-]+$/;
return regex.test(id);
}
// Example Usage:
console.log(isValidProductId('PROD-123-XYZ')); // Output: true
console.log(isValidProductId('PROD_123')); // Output: false (contains an underscore)
console.log(isValidProductId('prod-123')); // Output: false (contains lowercase letters)Conclusion
The "Range out of order" error in JavaScript regular expressions is almost always caused by a hyphen (-) being placed in an ambiguous position within a character set ([...]).
- To fix the error and include a literal hyphen, place the hyphen at the very beginning or very end of the character set. For example,
[-abc]or[abc-]. This is the recommended best practice. - Alternatively, you can escape the hyphen with a backslash (e.g.,
[a\-b]), but this is often less readable.
By following this simple rule, you can avoid this common regex syntax error and reliably include hyphens in your character classes.