Reputation: 349
So I am extremely new to the Javascript world. I was practicing on codewars having to analyze a pin to make sure it only contained numbers and was either 4 or 6 characters. I looked at the most clever code and the answer was:
function validatePIN(pin) {
return /^(\d{4}|\d{6})$/.test(pin)
}
I've never seen the "/^(\d{4}|\d{6})$/" bit before. Could anyone tell me what this is called so I can research it on my own, or give me a breakdown of how it works?
Upvotes: 12
Views: 79205
Reputation: 46366
It's a regular expression literal, similar to using return new RegExp('^(\\d{4}|\\d{6})$').test(pin)
The "literal" part implies that it's a means of representing a specific data type as a string in code—just like true
and 'true'
are different, as one is a boolean literal and the other is a string literal.
Specifically, the regex ^(\d{4}|\d{6})$
breaks down to:
^ a string that starts with...
( either
\d a digit (0-9)...
{4} that repeats four times...
| or
\d a digit (0-9)...
{6} that repeats six times...
)
$ and then ends
So: '1234'
, '123456'
, etc would match. '123.00'
, '12345'
,'abc123'
,' 1234'
, ' 1234 '
would not match.
As noted by several others in the comments on Draco18s' answer there are several nuances to be aware of with using regex literals in JS:
The literal syntax doesn't require you to escape special characters within the regex pattern. Using the RegExp constructor requires you to represent the pattern as a string, which in turn requires escaping. Note the differences of the \
's between the two syntaxes.
Using a regex literal will treat the regex as a constant, whereas using new RegExp()
leaves life cycle management of the regex instance up to you.
The literal notation is compiled and implies a constant regex, whereas the constructor version is reparsed from the string, and so the literal is better optimized/cached. jsperf.com/regexp-literal-vs-constructor/4 Note: you can get basically the same effect by caching the new Regex in a variable, but the literal one is cached at the JIT step – user120242
In other words, using a regex literal can avoid potential performance pitfalls:
Example:
for (var i = 0; i < 1000; i++) {
// Instantiates 1x Regex per iteration
var constructed = new RegExp('^(\\d{4}|\\d{6})$')
// Instantiates 1 Regex
var literal = /^(\d{4}|\d{6})$/
}
Upvotes: 20
Reputation: 15268
Good reference for Javascript RegExp
http://www.regular-expressions.info/javascript.html
^ beginning of line
\d = all digits
{4} = repetition 4 times
| = "or"
$ end of line
your example tests for a 4 digit string or 6 digit string
Upvotes: 15
Reputation: 15941
It's a regular expression.
I tend to use http://www.regexpal.com/ when I want to try and find the expression I need, there's also http://regexr.com/ for learning about them (among other resources).
Upvotes: 27