Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What code is this? /^(\d{4}|\d{6})$/

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?

like image 774
Tucker Beauchamp Avatar asked Dec 21 '15 04:12

Tucker Beauchamp


People also ask

What does D in regex mean?

\d (digit) matches any single digit (same as [0-9] ). The uppercase counterpart \D (non-digit) matches any single character that is not a digit (same as [^0-9] ). \s (space) matches any single whitespace (same as [ \t\n\r\f] , blank, tab, newline, carriage-return and form-feed).

What does \s mean in regex?

The regular expression \s is a predefined character class. It indicates a single whitespace character. Let's review the set of whitespace characters: [ \t\n\x0B\f\r]

How would you match the date format dd mm yyyy?

To match a date in mm/dd/yyyy format, rearrange the regular expression to ^(0[1-9]|1[012])[- /.] (0[1-9]|[12][0-9]|3[01])[- /.] (19|20)\d\d$. For dd-mm-yyyy format, use ^(0[1-9]|[12][0-9]|3[01])[- /.]


2 Answers

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).

like image 112
Draco18s no longer trusts SE Avatar answered Sep 21 '22 11:09

Draco18s no longer trusts SE


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})$/ 
    }
    
like image 22
STW Avatar answered Sep 19 '22 11:09

STW