How to split a long regular expression into multiple lines in JavaScript?
You could convert it to a string and create the expression by calling new RegExp()
:
var myRE = new RegExp (['^(([^<>()[\]\\.,;:\\s@\"]+(\\.[^<>(),[\]\\.,;:\\s@\"]+)*)', '|(\\".+\\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.', '[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\\.)+', '[a-zA-Z]{2,}))$'].join(''));
Notes:
- when converting the expression literal to a string you need to escape all backslashes as backslashes are consumed when evaluating a string literal. (See Kayo's comment for more detail.)
RegExp
accepts modifiers as a second parameter/regex/g
=>new RegExp('regex', 'g')
[Addition ES20xx (tagged template)]
In ES20xx you can use tagged templates. See the snippet.
Note:
- Disadvantage here is that you can't use plain whitespace in the regular expression string (always use
\s
,\s+
,\s{1,x}
,\t
,\n
etc).
(() => { const createRegExp = (str, opts) => new RegExp(str.raw[0].replace(/\s/gm, ""), opts || ""); const yourRE = createRegExp` ^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)| (\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])| (([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`; console.log(yourRE); const anotherLongRE = createRegExp` (\byyyy\b)|(\bm\b)|(\bd\b)|(\bh\b)|(\bmi\b)|(\bs\b)|(\bms\b)| (\bwd\b)|(\bmm\b)|(\bdd\b)|(\bhh\b)|(\bMI\b)|(\bS\b)|(\bMS\b)| (\bM\b)|(\bMM\b)|(\bdow\b)|(\bDOW\b) ${"gi"}`; console.log(anotherLongRE);})();
Extending @KooiInc answer, you can avoid manually escaping every special character by using the source
property of the RegExp
object.
Example:
var urlRegex= new RegExp('' + /(?:(?:(https?|ftp):)?\/\/)/.source // protocol + /(?:([^:\n\r]+):([^@\n\r]+)@)?/.source // user:pass + /(?:(?:www\.)?([^\/\n\r]+))/.source // domain + /(\/[^?\n\r]+)?/.source // request + /(\?[^#\n\r]*)?/.source // query + /(#?[^\n\r]*)?/.source // anchor);
or if you want to avoid repeating the .source
property you can do it using the Array.map()
function:
var urlRegex= new RegExp([ /(?:(?:(https?|ftp):)?\/\/)/ // protocol ,/(?:([^:\n\r]+):([^@\n\r]+)@)?/ // user:pass ,/(?:(?:www\.)?([^\/\n\r]+))/ // domain ,/(\/[^?\n\r]+)?/ // request ,/(\?[^#\n\r]*)?/ // query ,/(#?[^\n\r]*)?/ // anchor].map(function(r) {return r.source}).join(''));
In ES6 the map function can be reduced to:.map(r => r.source)
Using strings in new RegExp
is awkward because you must escape all the backslashes. You may write smaller regexes and concatenate them.
Let's split this regex
/^foo(.*)\bar$/
We will use a function to make things more beautiful later
function multilineRegExp(regs, options) { return new RegExp(regs.map( function(reg){ return reg.source; } ).join(''), options);}
And now let's rock
var r = multilineRegExp([ /^foo/, // we can add comments too /(.*)/, /\bar$/]);
Since it has a cost, try to build the real regex just once and then use that.