Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript regex multiline flag doesn't work

People also ask

How do you turn on multi line flags?

The multiline mode is enabled by the flag m . It only affects the behavior of ^ and $ . In the multiline mode they match not only at the beginning and the end of the string, but also at start/end of line.

Which flag will search over multiple lines?

The m flag indicates that a multiline input string should be treated as multiple lines. For example, if m is used, ^ and $ change from matching at only the start or end of the entire string to the start or end of any line within the string.

What is multi line in regex?

Multiline option, or the m inline option, enables the regular expression engine to handle an input string that consists of multiple lines. It changes the interpretation of the ^ and $ language elements so that they match the beginning and end of a line, instead of the beginning and end of the input string.

What is M in regex?

The m flag is used to specify that a multiline input string should be treated as multiple lines. If the m flag is used, ^ and $ match at the start or end of any line within the input string instead of the start or end of the entire string.


You are looking for the /.../s modifier, also known as the dotall modifier. It forces the dot . to also match newlines, which it does not do by default.

The bad news is that it does not exist in JavaScript (it does as of ES2018, see below). The good news is that you can work around it by using a character class (e.g. \s) and its negation (\S) together, like this:

[\s\S]

So in your case the regex would become:

/<div class="box-content-5">[\s\S]*<h1>([^<]+?)<\/h1>/i

As of ES2018, JavaScript supports the s (dotAll) flag, so in a modern environment your regular expression could be as you wrote it, but with an s flag at the end (rather than m; m changes how ^ and $ work, not .):

/<div class="box-content-5">.*<h1>([^<]+?)<\/h1>/is

You want the s (dotall) modifier, which apparently doesn't exist in Javascript - you can replace . with [\s\S] as suggested by @molf. The m (multiline) modifier makes ^ and $ match lines rather than the whole string.


[\s\S] did not work for me in nodejs 6.11.3. Based on the RegExp documentation, it says to use [^] which does work for me.

(The dot, the decimal point) matches any single character except line terminators: \n, \r, \u2028 or \u2029.

Inside a character set, the dot loses its special meaning and matches a literal dot.

Note that the m multiline flag doesn't change the dot behavior. So to match a pattern across multiple lines, the character set [^] can be used (if you don't mean an old version of IE, of course), it will match any character including newlines.

For example:

/This is on line 1[^]*?This is on line 3/m

where the *? is the non-greedy grab of 0 or more occurrences of [^].


The dotall modifier has actually made it into JavaScript in June 2018, that is ECMAScript 2018.
https://github.com/tc39/proposal-regexp-dotall-flag

const re = /foo.bar/s; // Or, `const re = new RegExp('foo.bar', 's');`.
re.test('foo\nbar');
// → true
re.dotAll
// → true
re.flags
// → 's'