\w: the word character class, underscore included
\w matches one ASCII letter, one ASCII digit or an underscore. It does not match accented letters, hyphens or any non-Latin script, whatever flags you set.
At a glance
- Syntax
- \w
- Equivalent to
- [A-Za-z0-9_]
- Negated form
- \W
- Underscore
- included, which is why it has no word boundary around it
- Accented letters
- excluded, é and ñ are not word characters
- Unicode alternative
- [\p{L}\p{N}_] with the u flag, when you need real letters
In detail
The class is defined as ASCII letters, ASCII digits and the underscore, which is a definition inherited from identifier syntax rather than from anything to do with human words. That heritage explains both of its surprises: the underscore is in, and everything outside ASCII is out.
Matching /\w+/g against a phrase such as "café au_lait-2" makes both consequences visible at once. The result is caf, au_lait and 2. The accented e ends the first match, the underscore does not break the second, and the hyphen splits the third away. None of that is what a reader would call word splitting.
This is why /^\w+$/ is a poor validator for anything a person types. It rejects names with diacritics, rejects anything in a non-Latin script, and accepts a string of underscores. If the intent is an identifier, that is exactly right and the name is honest. If the intent is a display name, the pattern is quietly discriminating.
With the u flag you can write [\p{L}\p{N}_] instead, which matches letters and numbers in any script plus the underscore. It is longer, it needs the flag, and it is the correct spelling any time the pattern is going to see real names.
Examples
"café au_lait-2".match(/\w+/g); // ["caf", "au_lait", "2"]The accented e is not a word character, the underscore is, and the hyphen is not.
/^\w+$/.test("café"); // false
/^[\p{L}\p{N}_]+$/u.test("café"); // true
/^[\p{L}\p{N}_]+$/u.test("naïve_2"); // trueThings that catch people out
- /^\w+$/ rejects every name with an accent in it. Used as a signup validator it fails a large share of real users and looks like a bug in the form.
- The underscore being a word character means \bfoo\b does not find foo inside foo_bar, which is usually right for identifiers and usually wrong for prose.
- \w does not include the hyphen, so a pattern for slugs or hyphenated surnames needs [\w-] with the hyphen last or escaped.
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 →\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.
\b: word boundaries, underscores and accented letters
\b is a zero width assertion defined entirely in terms of \w, which is why user_name has no internal boundary and café has none at its end.
\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.
\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.
\S: non whitespace, and the [\s\S] any character trick
\S is the complement of \s, which makes it a blank check in one character. Paired with \s it also gives the standard match anything class.
The dot: any character except a line terminator
What the dot matches by default, the four characters it skips, how the u and s flags change it, and why it needs no escape inside a character class.
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