\d: the digit class, and the digits it refuses
\d matches a single character in the range 0 to 9 and nothing else. Unlike Python and .NET, JavaScript keeps it ASCII only even when the u flag is set.
At a glance
- Syntax
- \d
- Equivalent to
- [0-9], in every JavaScript pattern
- Negated form
- \D
- Unicode aware
- no, not even with the u flag
- Unicode alternative
- \p{Nd} with the u flag
- Other engines
- Python's re and .NET match Unicode decimal digits by default
In detail
The definition is unusually simple: \d is a shorthand for the character class [0-9], one character, no exceptions. It carries no notion of grouping, sign or decimal point, so a pattern that needs a number rather than a digit needs a quantifier and usually a good deal more besides.
The interesting part is what it excludes. Arabic-Indic digits, Devanagari digits and full width digits are all decimal digits in Unicode and none of them match \d in JavaScript, even with the u flag on. Matching /\d+/gu against a string containing Arabic-Indic numerals returns only the ASCII run. Switching to \p{Nd} picks up both.
This is a real portability trap rather than a curiosity, because Python's re module and .NET both make \d Unicode aware by default. A pattern lifted from a Python codebase into JavaScript silently narrows, and a pattern going the other way silently widens. The tester's code tab will hand you the equivalent snippet in eight languages, but no translation can reconcile a definition that differs between them.
Inside a character class the shorthand keeps working and combines freely: [\d.] means a digit or a full stop, and [^\d] means the same thing as \D. That composability is why \d survives even in patterns where writing [0-9] would be just as short.
Examples
const m = /\d{3}/.exec("abc123def");
m[0]; // "123"
m.index; // 3"\u0661\u0662\u0663 45".match(/\d+/gu); // ["45"]
"\u0661\u0662\u0663 45".match(/\p{Nd}+/gu); // ["١٢٣", "45"]The first three characters are Arabic-Indic digits. They are decimal digits in Unicode and still not matched by \d.
Things that catch people out
- \d does not mean a number. /\d+/ against "3.14" returns 3 and 14 as two separate matches, because the full stop is not part of the class.
- A pattern copied from Python quietly changes meaning here, since Python's \d matches Unicode decimal digits and this one does not.
- Adding the u flag does not widen \d. If you need non-ASCII digits you have to write \p{Nd}, and that escape needs u to work at all.
Try it: Regex Tester
Type a pattern and a test string, watch every match highlight as you go, read a plain English breakdown of each token, and check the numbered and named groups it captured.
Regex Tester
LOCAL · Browser-OnlyTest and debug regular expressions with live matching and highlights
Related Regex syntax
All regex syntax →\D: everything that is not a digit
\D is the exact complement of \d, which makes it a stripping and splitting tool. It also matches newlines, spaces and every letter in every script.
[a-z] ranges: code point order and the A-z bug
Ranges inside a character class run by code point, which is why [A-z] quietly includes six punctuation characters and [a-Z] is a syntax error.
\p{...}: Unicode property escapes, and the flag they need
Property escapes match by Unicode category or script instead of by code point range. Without the u flag they compile into something else entirely.
\w: the word character class, underscore included
\w is exactly [A-Za-z0-9_] in JavaScript. That includes the underscore and excludes every accented letter, which is where most \w bugs come from.
\W: non word characters, and the underscore it will not match
\W is the complement of \w, so it never matches an underscore and always matches an accented letter. Both surprises show up when splitting identifiers.
\s: every whitespace character it actually matches
The full list behind \s in JavaScript, including the no break space and the byte order mark, plus the one invisible character it deliberately skips.
Tools for this
- Regex Tester Free online regex tester - test and debug regular expressions with live matching and highlights
- Regex Playground Regex playground with live match highlighting, named groups, find and replace, and shareable links