RegExp.prototype.dotAll
Returns whether the regular expression was created with the s flag.
get RegExp.prototype.dotAll- Added in JavaScript ES2018
Return value
booleantrue if the s flag is set, false otherwise.
Errors
TypeError if accessed on a value that is not a RegExp object (other than RegExp.prototype itself).
Changelog
- PHP ES2018The s flag and the dotAll accessor were introduced; before this the idiom was the character class [\s\S].
dotAll reports whether the s flag is set. By default . matches any character except a line terminator; with s, it matches those too.
Four characters, not one
The excluded set is LF (\n), CR (\r), U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR. Code that only tested with \n can still fail on the other three, which is why the pre-2018 workaround [\s\S] — or [^] — remains correct: those classes cover every character by construction.
When to use it
Any time a pattern needs to span a line break: a block of markup, a fenced code section, a multi-line log entry. Pair it with a lazy quantifier — /<p>(.*?)<\/p>/s, not (.*) — because with s a greedy .* will happily swallow the entire document to reach the last closing tag.
It is independent of m: s changes what . matches, m changes what ^ and $ anchor to. Combine them as /pattern/ms when you need both.
Example
When to use it
- Capture the body of a multi-line block comment or markup element
- Match a log entry whose stack trace spans several lines
- Grab everything between two markers regardless of line breaks
Frequently asked questions
How do I make . match a newline in JavaScript?
Add the s flag: /a.b/s. In environments predating ES2018, use the character class [\s\S] or [^] instead, both of which match every character including line terminators.
Is dotAll the same as the multiline flag?
No. s (dotAll) changes what . matches; m (multiline) changes what ^ and $ anchor to. They are independent and are often used together as /pattern/ms.
Should I use the s flag or [\s\S]?
Use s for readability in modern code. [\s\S] is still useful when only part of the pattern should cross line breaks, since a flag applies to every dot in the expression while the class applies only where you write it.
More examples
Greedy dots become dangerous with s
Without s, the newline acted as an accidental boundary that kept a greedy .* honest. Once s removes that boundary you must make the quantifier lazy, or the match runs to the last closing tag in the string.
const doc = "<b>one</b>\n<b>two</b>";
console.log(/<b>(.*)<\/b>/s.exec(doc)[1]); // spans both tags
console.log(/<b>(.*?)<\/b>/s.exec(doc)[1]); // "one"
console.log([...doc.matchAll(/<b>(.*?)<\/b>/gs)].map(m => m[1]));s and m solve different problems
m only affects the anchors, s only affects the dot. The last line shows why both flags exist: matching a multi-line span that is also anchored to line boundaries needs the pair.
const text = "start\nmiddle\nend";
console.log(/start.end/.test(text)); // false
console.log(/start.end/m.test(text)); // false - m does not touch .
console.log(/start.*end/s.test(text)); // true
console.log(/^middle$/m.test(text)); // true
console.log(/^middle$/s.test(text)); // false
console.log(/^start.*end$/ms.test(text)); // true
Discussion