Differences between Javascript regexp literal and constructor
There are two problems:
The /
are not part of the expression. They are delimiters, marking a regex literal. They have to be removed if you use RegExp
, otherwise they match a slash literally.
Secondly, the backslash is the escape character in string literals. To create a literal \
for the expression, you have to escape it in the string.
Thus, the equivalent would be:
new RegExp("rt:([^@]+)@(\\d+)")
Especially the escaping makes expression a bit more difficult to write if you want to use RegExp
. It is actually only needed if you want to create expression dynamically, that is, if you want to include text stored in a variable for example. If you have a fixed expression, a literal /.../
is easier to write and more concise.
JavaScript: RegExp constructor vs RegEx literal
The key difference is that literal REGEX can't accept dynamic input, i.e. from variables, whereas the constructor can, because the pattern is specified as a string.
Say you wanted to match one or more words from an array in a string:
var words = ['foo', 'bar', 'orange', 'platypus'];
var str = "I say, foo, what a lovely platypus!";
str.match(new RegExp('\\b('+words.join('|')+')\\b', 'g')); //["foo", "platypus"]
This would not be possible with a literal /pattern/
, as anything between the two forward slashes is interpreted literally; we'd have to specify the allowed words in the pattern itself, rather than reading them in from a dynamic source (the array).
Note also the need to double-escape (i.e. \\
) special characters when specifying patterns in this way, because we're doing so in a string - the first backslash must be escaped by the second so one of them makes it into the pattern. If there were only one, it would be interpreted by JS's string parser as an escaping character, and removed.
RegExp Object Literal notation vs Constructor notation difference
The new RegExp()
syntax doesn't use forward slashes /
as the delimiter. It's assumed that the entire string is the regex. Also, backslashes must be escaped, since this is a requirement of strings when you aren't referencing an escape character.
These are the same:
digits.match(new RegExp("\\d+")); // 2
digits.match(/\d+/); // 2
Difference between RegExp constructor and Regex literal test function?
From RegExp.test()
:
test
called multiple times on the same global regular expression instance will advance past the previous match.
So basically when you have an instance of RegExp
, each call to test
advances the matcher. Once you've found the first d
, it will look beyond that and try to find another d
. Well, there are none anymore, so it returns false
.
On the other hand, when you do:
/d/gi.test("Douglas Enas")
You create a new RegExp
instance every time on the spot, so it will always find that first d
(and thus return true
).
When to use RegExp constructor vs regular expression literal?
MDN says:
Regular expression literals provide compilation of the regular expression when the script is loaded. When the regular expression will remain constant, use this for better performance.
Using the constructor function provides runtime compilation of the regular expression. Use the constructor function when you know the regular expression pattern will be changing, or you don't know the pattern and are getting it from another source, such as user input.
In practice, I use the literal form for simple regular expressions. For more complex expressions, I put them together piece-wise with string concatenation and use the constructor.
BONUS: For those complicated regular expressions, a tool like debuggex really helps.
Javascript RegExp different results from constructor and literal
When creating regex instance from RegExp
constructor, you need to escape the \
with another \
as it is a escape-sequence.
The first one works right, because there is no \
in the String
, whereas in others, it is there, unescaped.
Escaped Version
Difference between RegExp constructor and Regex literal test function?
From RegExp.test()
:
test
called multiple times on the same global regular expression instance will advance past the previous match.
So basically when you have an instance of RegExp
, each call to test
advances the matcher. Once you've found the first d
, it will look beyond that and try to find another d
. Well, there are none anymore, so it returns false
.
On the other hand, when you do:
/d/gi.test("Douglas Enas")
You create a new RegExp
instance every time on the spot, so it will always find that first d
(and thus return true
).
Javascript: Difference in Regex String and Regex
When you use the new RegExp()
constructor to construct a regex from a string, you shouldn't include the leading and trailing /
within the string. The /.../
form is only to be used when specifying a regex literal, which isn't what you're doing here.
When you do, say, var r = new RegExp('/foo/')
, the regex you're actually getting is equivalent to doing var r = /\/foo\//
, which clearly isn't what you want. So your constructor should actually look like this:
var regex = new RegExp('^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9@#$-/:-?{-~!"^_`\[\]])+((?!' + $scope.username + ').)*$');
// ↑↑ ↑↑
// no "/" at the locations pointed to above
You probably also need to double your backslashes (since backslashes are escape characters in strings, but not in regex literals). So, [0-9@#$-/:-?{-~!"^_`\[\]]
needs to become [0-9@#$-/:-?{-~!"^_`\\[\\]]
.
What is the difference between using new RegExp and using forward slash notation to create a regular expression?
If you use the constructor to create a new RegExp object instead of the literal syntax, you need to escape the \
properly:
new RegExp("^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$")
This is necessary as in JavaScript any unknown escape sequence \x
is interpreted as x
. So in this case the \.
is interpreted as .
.
Related Topics
Can You Determine If Chrome Is in Incognito Mode via a Script
How to Force Angular2 to Post Using X-Www-Form-Urlencoded
Getting the Object's Property Name
Shrink Div to Text That's Wrapped to Its Max-Width
How to Add Bootstrap in Angular 6 Project
Accessing Localstorage from a Webworker
CSS Height 100% Percent Not Working
Storing Image Data for Offline Web Application (Client-Side Storage Database)
How to Move All HTML Element Children to Another Parent Using JavaScript
Replace Multiple Whitespaces with Single Whitespace in JavaScript String
Javascript/Jquery: Test If Window Has Focus
JavaScript Regex Hangs (Using V8)
What Happens When Using This.Setstate Multiple Times in React Component
Why Is the Variable Holding the Input Value Always Logged as Empty
Print a Div Using JavaScript in Angularjs Single Page Application
Add Elements to the Dom Given Plain Text HTML Using Only Pure JavaScript (No Jquery)