RegExp.prototype.multiline
Returns whether the regular expression was created with the m flag.
get RegExp.prototype.multiline- Added in JavaScript ES3 (1999)
Return value
booleantrue if the m 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 ES6multiline became an accessor on RegExp.prototype rather than an own data property of each instance.
- PHP ES2018The separate s (dotAll) flag was introduced; m has never affected what . matches, but the two are often confused.
multiline reports whether the m flag is set. The flag changes exactly two things and nothing else: ^ stops meaning "start of string" and starts meaning "start of a line", and $ likewise becomes "end of a line".
What counts as a line break
Four characters: LF (\n), CR (\r), U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR. That matters for Windows-style \r\n text, where CR and LF each end a line — so /^.*$/gm yields an empty match between them. Trim the \r, or match \r?$ explicitly.
Two common mix-ups
First, m does not make . match newlines — that is the s (dotAll) flag, and the two are independent. Second, m is usually paired with g: on its own it lets an anchored pattern match at any line, but you still only get the first match.
If you need the true string boundaries while m is in effect, \A and \z serve that role in Unicode-aware mode.
Example
When to use it
- Pull every line of a log that starts with a timestamp
- Comment out or indent each line of a block of text
- Find lines that end with a trailing comma across a config blob
Frequently asked questions
Why does ^ not match after a newline in my regex?
Because the m flag is missing. Without it, ^ anchors to the start of the whole string and $ to its end; with it, both anchor to line boundaries. Add m, usually together with g so you get every line.
Does the multiline flag make . match newlines?
No. That is the s (dotAll) flag. m changes only what ^ and $ anchor to; the two flags are independent and can be combined as /pattern/ms.
Why do I get empty matches on Windows line endings?
Because CR and LF each count as a line terminator, so \r\n creates a zero-length line between them. Normalise with text.replace(/\r\n/g, "\n") before matching, or write \r?$ in your pattern.
More examples
CRLF produces an extra empty line
The empty string between \r and \n is a real line as far as the m flag is concerned. Normalising line endings before matching is usually simpler than encoding \r? into every pattern.
console.log("x\ny".match(/^.*$/gm)); // [ "x", "y" ]
console.log("x\r\ny".match(/^.*$/gm)); // [ "x", "", "y" ]
// CR and LF each terminate a line, so match \r explicitly:
console.log("x\r\ny".match(/^.*(?=\r?$)/gm));
console.log("x\r\ny".replace(/\r\n/g, "\n").match(/^.*$/gm));m and s are independent
The m flag only affects the anchors and the s flag only affects the dot. Reaching for m when you meant s produces a silent non-match rather than an error, which is what makes the mix-up expensive.
const block = "one\ntwo";
console.log(/one.two/.test(block)); // false - . skips \n
console.log(/one.two/m.test(block)); // false - m does not change .
console.log(/one.two/s.test(block)); // true - s does
console.log(/^two$/m.test(block)); // true
console.log(/^two$/s.test(block)); // false
Discussion