\W matches any single character that is not a word character. Word characters are letters, digits, and underscore ([A-Za-z0-9_]). Spaces, hyphens, and punctuation all match \W.
Remember
\w → letter, digit, or underscore
\W → everything else (space, -, !, @, …)
\W+ → one or more non-word characters
/\W/.test("hello") → false
/\W/.test("hello!") → true
/\W/.test("user_name") → false (_ is \w)
/\W/.test("user-name") → true (- is \W)
Use \W when you care about “not a word character” — detect it, strip it, or split on it.
Write /\W/ to match one non-word character.
Add + for a run of separators (\W+).
Use the g flag with replace or match to process every match.
Remember: underscore is a word character — it does not match \W.
Piece
Required?
Role
\W in the pattern
Yes
Match one non-word character
Quantifier
Optional
Repeat (\W+, \W*, \W{2})
g flag
Optional
Find or replace every non-word character
Anchors / inverse
Optional
/^\w+$/ or !/\W/.test(str) for word-only text
Pseudocode
Pseudocode
pattern has "\W"
read next character ch from the string
if ch is letter, digit, or underscore:
fail this path
else:
accept ch as a non-word match
common actions:
test(str) → true if any symbol/space/punct exists
replace(/\W/g, "") → keep letters, digits, _
split(/\W+/) → tokens between separators
Reference
Cheat Sheet
Keep these facts handy while cleaning punctuation and symbols.
Topic
Detail
Meaning
Not [A-Za-z0-9_]
Equivalent
[^\w]
Opposite
\w = word character
Underscore
Matches \w, not \W
Strip symbols
str.replace(/\W/g, "")
Split tokens
str.split(/\W+/)
Standard
ES3+ (universal)
Try it
Live Preview
Run common \W operations on sample strings.
Browser demo of the RegExp \W non-word escape — same ideas as the examples below.
Result
text = "hello"
/\W/.test(text)
→ false
/* letters are word characters */
Code
JavaScript Examples
Short, copy-ready snippets. Open DevTools Console, or use Try It Yourself for a live editor.
Example 1 — Detect Any Non-Word Character
Return true when punctuation, spaces, or symbols appear — and see why underscore does not.
JavaScript
console.log(/\W/.test("hello")); // false
console.log(/\W/.test("hello!")); // true
console.log(/\W/.test("user_name")); // false (_ is word char)
console.log(/\W/.test("user-name")); // true
Use \W+ as a delimiter. One or more non-word characters become cut points.
Mixed separators work. Commas, semicolons, and spaces all split the first string.
Tokens are word runs. Each piece is letters/digits/_ between separators.
Simple lists."js,regex,pattern" splits cleanly on each comma.
Edge Cases & Pitfalls
Check these before relying on \W in real projects.
trap
Underscore is not\W
_ is a word character. "a_b" has no \W match; "a-b" does.
ascii
Default \w/\W are ASCII-oriented
Without Unicode flags/properties, “word” means [A-Za-z0-9_]. Accented letters may match \W in default mode.
escape
new RegExp needs double escaping
Write new RegExp("\\W"). In a string pattern argument you need two backslashes.
split
Leading/trailing separators can yield empty parts
",a,".split(/\W+/) may include empty strings. Filter with .filter(Boolean) when needed.
Compatibility
Browser & Runtime Support
The \W non-word escape is core regex syntax (ES3+) and works everywhere JavaScript runs.
✓ Baseline · ES3+
RegExp \W
Supported in every modern and legacy browser, plus all Node.js versions. No polyfill required.
100%Universal support
Google ChromeSupported · Desktop & Mobile
Full support
Mozilla FirefoxSupported · Desktop & Mobile
Full support
Apple SafariSupported · macOS & iOS
Full support
Microsoft EdgeSupported · Chromium
Full support
Internet ExplorerNo native support · Use a polyfill
Polyfill
OperaSupported · Modern versions
Full support
Samsung InternetSupported · Android
Full support
BunSupported · JavaScript runtime
Supported
DenoSupported · JavaScript runtime
Supported
Node.jsSupported · Server runtime
Supported
Android WebViewSupported · Modern WebView
Full support
\WExcellent
Bottom line: Safe to use in any JavaScript environment. Pair with \w when you need both sides of the word-character check.
Analysis
Performance Notes
Approach
Cost
Best for
/\W/.test(str)
O(n)
Quick “has symbol?” checks
str.replace(/\W/g, "")
O(n)
Stripping punctuation
str.split(/\W+/)
O(n)
Tokenizing on separators
Character-class style matches are cheap. Prefer \w when you want word characters directly, and \W when stripping or splitting on everything else is clearer.
Remember
Key Takeaways
Role:\W matches one character that is not a word character.
Opposite of \w: letters/digits/_ vs everything else.
Cleanup:replace(/\W/g, "") strips punctuation and spaces.
Split:split(/\W+/) tokenizes on commas, spaces, and symbols.
One line:\W means “not a word character” — detect symbols, strip them, or split on them (and remember _ is \w).
Frequently Asked Questions
\W matches any single character that is NOT a word character. Word characters are letters A–Z/a–z, digits 0–9, and underscore (_). Spaces, hyphens, and punctuation all satisfy \W.
\w matches word characters (letters, digits, underscore). \W is the uppercase inverse and matches everything except those characters—spaces, symbols, and punctuation.
Yes. In standard JavaScript regex, \W and [^\w] are equivalent—they both match one non-word character.
No. Underscore (_) is a word character and matches \w, not \W. Hyphens, spaces, and @ symbols do match \W.
Use replace with the global flag: str.replace(/\W/g, ""). Every non-word character is removed, leaving letters, digits, and underscores.
The \W non-word shorthand is core regex syntax since ES3. It works in every browser and Node.js version.