Whitespace in Regular Expressions
Whitespace handling is one of the most common tasks in string processing — trimming user input, collapsing sloppy formatting, splitting on any whitespace, or detecting where text begins on a line. Regex has purpose-built shortcuts for whitespace that work identically in every major language: \s matches any whitespace character, \S matches any non-whitespace. Master these two and 90% of your whitespace problems disappear.
The Whitespace Character Class
\s matches any of the following characters:
— Space (U+0020)\t— Tab (U+0009)\n— Newline / line feed (U+000A)\r— Carriage return (U+000D)\f— Form feed (U+000C)\v— Vertical tab (U+000B)
In Unicode-aware modes (JavaScript with the u flag, Python 3 by default, .NET), \s also matches non-breaking space (U+00A0), en space, em space, and all other Unicode whitespace characters. This is usually what you want when handling real-world text pasted from Word documents or web pages.
The Core Patterns
Match one or more whitespace characters
/\s+/g // any run of whitespace — the workhorse
/\s/g // exactly one whitespace character
/\s{2,}/g // two or more (find double spaces)
/\s*/g // zero or more (rarely useful — matches empty positions)Match only spaces (not tabs/newlines)
/ +/g // literal space, one or more
/[ ]+/g // same thing, more explicit
/[ \t]+/g // spaces or tabs (horizontal whitespace only)Trim leading and trailing whitespace
/^\s+|\s+$/g // classic trim pattern
/^\s+/ // leading only
/\s+$/ // trailing onlyNon-whitespace
/\S+/g // any run of non-whitespace — useful for word extraction
/\S/g // any single non-whitespace characterLanguage-Specific Usage
JavaScript
// Remove ALL whitespace
' hello world '.replace(/\s+/g, '');
// → 'helloworld'
// Collapse whitespace + trim
' hello world '.replace(/\s+/g, ' ').trim();
// → 'hello world'
// Trim only
' hello '.replace(/^\s+|\s+$/g, '');
// → 'hello' (or just use .trim())
// Split on any whitespace run
'the quick\tbrown\nfox'.split(/\s+/);
// → ['the', 'quick', 'brown', 'fox']
// Count words
str.trim().split(/\s+/).length;Python
import re
# Remove all whitespace
re.sub(r'\s+', '', ' hello world ')
# → 'helloworld'
# Collapse and trim
' '.join(' hello world '.split()) # Pythonic, no regex needed
re.sub(r'\s+', ' ', s).strip() # regex version
# Split on any whitespace
s.split() # default splits on any whitespace run
re.split(r'\s+', s.strip()) # explicit regex version
# Count words
len(re.findall(r'\S+', s))PHP
// Remove all whitespace
preg_replace('/\s+/', '', $s);
// Collapse and trim
trim(preg_replace('/\s+/', ' ', $s));
// Split on any whitespace
preg_split('/\s+/', trim($s));
// PHP built-in: trim($s) is simpler for basic trimmingCommon Pitfalls
The dot-matches-newline problem
In most regex flavours, . matches any character except newlines. If your text has embedded newlines and you want to match everything, use [\s\S] (the "whitespace or non-whitespace" trick — literally any character) or enable the DOTALL / single-line flag: /pattern/s in Perl/PHP/Python, /pattern/s also in JavaScript (ES2018+).
Non-breaking space traps
Text copied from Word or webpages often contains U+00A0 (non-breaking space) which LOOKS identical to a space but is not U+0020. In JavaScript (no u flag), \s DOES match it. In some other flavours it does not. If you have to trim non-breaking spaces explicitly: /[\s\u00a0]+/g.
Zero-width matches
/\s*/ (star, not plus) matches ZERO or more whitespace characters — which matches the empty position at every character boundary. Using replace(/\s*/g, 'X') on "abc" produces "XaXbXcX". Almost always use + (one or more) instead of *.
Multiline mode changes ^ and $
By default, ^ and $ match the start and end of the whole string. With the m flag, they also match the start and end of each line — so /^\s+/gm strips leading whitespace from every line, not just the first.
Whitespace Cheatsheet
| Goal | Pattern | Notes |
|---|---|---|
| Remove all whitespace | /\s+/g → "" | Aggressive — kills newlines too |
| Trim ends | /^\s+|\s+$/g → "" | Or use .trim()/.strip() ✅ |
| Collapse runs | /\s+/g → " " | Chain with .trim() after |
| Only spaces (no tabs) | / +/g | Literal space class |
| Horizontal whitespace | /[ \t]+/g | Spaces + tabs, no newlines |
| Non-whitespace runs | /\S+/g | Extract words |
Testing Your Whitespace Regex
Use the live Regex Tester with this test string (paste it exactly, with the mixed whitespace intact):
Leading spaces
mid line with spaces
tab here and there
trailing spaces
- Try
/\s+/g— should highlight every whitespace run - Try
/ +/g— should skip tabs and newlines - Try
/\S+/g— should highlight the words only - Try
/^\s+/gm— should highlight the indentation on each line