RegExp.test not giving correct result

2019-08-20 11:18发布

问题:

In the following code, I pass a FormControl which contains a password. I expect that when the password is aA1[11], the RegExp.test method should return false but it returns true! Why my code is returning null instead of error object { validatePassword: { valid: false, message: 'password must contain 1 small-case letter [a-z], 1 capital letter [A-Z], 1 digit[0-9], 1 special character and the length should be between 6-10 characters' }

Shouldn't this forward look up fail the match (?=.*[!@#$%^&*()_+}{":'?&gt.<,])

  validatePassword(control: FormControl) {

    let password: string = control.value;
 /*    So the rule for password is
     6-10 length
     contains a digit
     contains a lower case alphabet
     contains an upper case alphabet
     contains one more special character from the list !@#$%^&*()_+}{":;'?/>.<,
     does not contain space
     */
    let REG_EXP = new RegExp('(?=^.{6,10}$)(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+}{":\'?&gt.<,])(?!.*\\s).*$');
    /*RegExp's test method returns true if it finds a match, otherwise it returns false*/
    console.log('password: ',password);
    console.log('test result ',(REG_EXP.test(password)));
    return (REG_EXP.test(password)) ? null : {
      validatePassword: { //check the class ShowErrorsComponent to see how validatePassword is used.
        valid: false,
        message: 'password must contain 1 small-case letter [a-z], 1 capital letter [A-Z], 1 digit[0-9], 1 special character and the length should be between 6-10 characters'
      }
    }
  }

I am calling the above function from my Karma test case

fit('A password of length between 6-10 characters and containing at least 1 digit, at least  1 lowercase letter,  at least 1 upper case ' +
    'letter and but NOT at least 1 special character from the list !@#$%^&*()_+}{":;\'?/>.<, shall NOT be accepted',
    inject([HttpClient,HttpTestingController],(httpClient:HttpClient)=>{
      let helper = new HelperService(loaderService,httpClient);
      let passwordField = new FormControl();
      let password = 'aA1[11]';
      passwordField.setValue(password);
      let result = helper.validatePassword(passwordField);
      expect(result).toEqual(expectedErrorResponse);
    }));

The output I see in the console is

password:  aA1[11]
test result  true

回答1:

You can use below code to validate a password-

validatePassword(control: FormControl) {
    let password: string = control.value;

    let REG_EXP = /^(?=.*\d)(?=.*[#$@!%&*?])[A-Za-z\d#$@!%&*?]{6,10}$/i; // modify as per your requirement, currently it accept atleast 1 character,1 special character,1 [0-9] number, length between 6 to 10.

    if(!REG_EXP.test(password)) { 
    return {  'validatePassword': { //check the class ShowErrorsComponent to see how validatePassword is used.
        'valid': false,
        'message': 'password must contain 1 small-case letter [a-z], 1 capital letter [A-Z], 1 digit[0-9], 1 special character and the length should be between 6-10 characters'
      } 
    }
    }
  }


回答2:

The issue was with regex. I changed &amp to just & and &quot to " and &gt to > and &lt to <. It seems that in my code (angular), the letters after & were being treated literally. so the a in aA1[11] was matched with a in &amp