Elder
Elder

Reputation: 363

Regex validate PIN code JS

I'm trying to solve this task:

ATM machines allow 4 or 6 digit PIN codes and PIN codes cannot contain anything but exactly 4 digits or exactly 6 digits.

If the function is passed a valid PIN string, return true, else return false.

eg:

validatePIN("1234") === true validatePIN("12345") === false validatePIN("a234") === false

And this is my code:

function validatePIN (pin) {
  if(pin.length === 4 ||  pin.length === 6 ) {
    if( /[0-9]/.test(pin))  {
      return true;
    }else {return false;}
  }else {
      return false;
      }
}

It shows that --- Wrong output for 'a234' - Expected: false, instead got: true ---Why? This /[0-9]/ shows only numbers?

Thank you in advance :)

Upvotes: 3

Views: 31615

Answers (7)

JJWesterkamp
JJWesterkamp

Reputation: 7916

As you can see in this regex example /[0-9]/ will match any string that has at least 1 number anywhere in it.

To fix this you can use quantifiers to match exactly either

  • 4 numbers: [0-9]{4}
  • 6 numbers: [0-9]{6}

Additionally, we want these regexes to actually match the entire string, using ^ at the start, and $ at the end of the regex. This will make sure nothing exists next to a matched pin code.
If we combine the 2 cases above in a capture group, and add the start- and end-delimiters, we end up with this regex:

/^([0-9]{4}|[0-9]{6})$/

Note: the [0-9] character set has a nice shorthand: \d, so the regex could be further simplified to:

/^(\d{4}|\d{6})$/


This single regex performs all the validation you need, so in your code validatePIN could be simplified as follows:

function validatePIN (pin) {
    return /^(\d{4}|\d{6})$/.test(pin);
}

console.log(validatePIN('1234')); // > true
console.log(validatePIN('123456')); // > true
console.log(validatePIN('123')); // > false
console.log(validatePIN('12345')); // > false

Upvotes: 7

vytasK
vytasK

Reputation: 47

JAVA: Check each PIN number against an array of numbers and fill in a boolean loop accordingly. If the boolean loop in the end is not all true, return false.

public static boolean validatePin(String pin) {

String[] arr1 = pin.split("");
String[] num = {"1","2","3","4","5","6","7","8","9","0"};
boolean[] bool = new boolean[arr1.length];


if(arr1.length != 6 && arr1.length != 4){
  return false;
}



for(int i = 0; i< arr1.length; i++){

    for(int j = 0; j<num.length; j++){

        if(arr1[i].equals(num[j])){
            bool[i] = true;
        }

    }

}

for(int i = 0; i <bool.length; i++){

  if(bool[i] == false){
    return false;
  }

}

return true;

}

Upvotes: 1

Jobelle
Jobelle

Reputation: 2834

You can use the regex

^(?=[0-9]*$)(?:.{4}|.{6})$

Explanation

 ^ # Start of string
     (?= # Assert that the following regex can be matched here: 
    [0-9]* # any number of digits (and nothing but digits) 
    $ # until end of string ) # (End of lookahead) 
    (?: # Match either 
    .{4} # 8 characters | # or 
    .{6} # 11 characters ) # (End of alternation) 
    $ # End of string

Upvotes: 2

yajiv
yajiv

Reputation: 2941

you can simply use this regex /^(\d{4}|\d{6})$/ to validate pin.

function validate(a){
    return /^(\d{4}|\d{6})$/.test(a);
}

console.log(validate('1234'));
console.log(validate('123a'));
console.log(validate('1234a'));
console.log(validate('123412'));

Upvotes: 1

Abhijit Kar ツ
Abhijit Kar ツ

Reputation: 1732

Have a look at the code

function validatePIN(pin) {
  if (/^(\d{4}|\d{6})$/.test(pin)) {
    return true;
  } else {
    return false;
  }
}

console.log(validatePIN("1234"));
console.log(validatePIN("a234"));
console.log(validatePIN("12345"));
console.log(validatePIN("123456"));

Explanation:

  1. You don't need to check the length manually, regex can do that, e.g. {4} or {6}
  2. You can use \d, instead of [0-9], it's a short hand
  3. Plus regex needs to be end to end, i.e. with start and end should be specified with ^ ... $

Upvotes: 1

rafaelgomesxyz
rafaelgomesxyz

Reputation: 1405

/[0-9]/ will match any number in the string, so it matches the "2" in "a234". You need to make it match only numbers, from beginning to end: /^[0-9]+$/ or /^\d+$/

Additionally, you can just use the regular expression /^(\d{4}|\d{6})$/ to match all strings containing 4 or 6 numbers.

/^(\d{4}|\d{6})$/.test("1234"); // true
/^(\d{4}|\d{6})$/.test("12345"); // false
/^(\d{4}|\d{6})$/.test("123456"); // true
/^(\d{4}|\d{6})$/.test("a234"); // false

Upvotes: 7

Arnold Gandarillas
Arnold Gandarillas

Reputation: 4322

Because you are not specifying where the number needs to be.

If there is a number in your expression it will be true that's all you are checking right now.

To correct that behavior you need to do this:

/^[0-9]+$/.test(pin)

With this you are saying that the "number" should start, contain and end in a number.

Upvotes: 1

Related Questions