\S: non whitespace, and the [\s\S] any character trick
\S matches any character that is not whitespace. Combined with \s in a single class it produces [\s\S], which matches every character including line terminators.
At a glance
- Syntax
- \S
- Equivalent to
- [^\s]
- Positive form
- \s
- Blank test
- /\S/.test(value) answers whether a string has any content at all
- Any character class
- [\s\S], which crosses newlines with no s flag needed
- Portability
- [\s\S] compiles in every engine, dotAll does not
In detail
As a single character test, \S is the shortest honest way to ask whether a string contains anything at all. A value of spaces, tabs and newlines returns false, and a value with one visible character returns true. That is a more useful check than a length test, which counts whitespace as content.
The bigger use is the pair. Putting both shorthands in one class gives [\s\S], a class containing whitespace or non whitespace, which is every character in existence including the four line terminators. It is the standard way to match across lines and it predates the s flag by two decades.
It is still worth reaching for after ES2018 for two reasons. It applies at exactly one position rather than changing every dot in the pattern, and it compiles in engines that never got dotAll. A pattern that has to travel between languages is safer written this way, and the tester's code tab will show you the same pattern in each of the eight it emits.
The contrast with the plain dot is stark on multi-line input. Matching /^.+$/ against a two line string returns null, because the dot cannot cross the newline and $ demands the end of the string. Swapping the dot for [\s\S] makes the same pattern match the whole thing.
Examples
/\S/.test(" \n "); // false, nothing but whitespace
/\S/.test(" x "); // true
"line1\nline2".match(/^.+$/); // null
"line1\nline2".match(/^[\s\S]+$/)[0]; // "line1\nline2""<a>\nx\n</a>".match(/<a>([\s\S]*?)<\/a>/)[1]; // "\nx\n"Only this quantifier crosses lines. Any dot elsewhere in the pattern keeps its normal meaning.
Things that catch people out
- [\s\S]* is unbounded and greedy, so on a large input it can scan the whole string and back again. Prefer the lazy form or a negated class when there is a known terminator.
- \S includes punctuation and symbols, so /^\S+$/ is not a check for a word. It only says the value has no spaces in it.
- Writing [\s\S] and then also setting the s flag is harmless but misleading, because it suggests the flag is doing something that the class already handled.
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 →\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.
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.
The s flag: dotAll mode
What dotAll changes, why it has no effect at all on character classes, and the [\s\S] idiom that did the same job before the s flag existed.
[abc]: character sets and what loses its meaning inside
A bracket set matches one character from a list. Most metacharacters go literal inside it, and only four keep any special meaning at all.
[^abc]: negated character sets that quietly cross newlines
A negated class matches one character that is not in the set, including line terminators. That is why a quoted string pattern runs across lines.
[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.
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