RegExp.prototype.multiline

Returns whether the regular expression was created with the m flag.

Signature
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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · javascript
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.

Example · javascript
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

  • Be the first to comment on this lesson.