Search code examples
javascriptregexvalidationsymbols

Regular Expression for symbol characters in JavaScript


I have a quick question about the regular expression for symbols like !@#$%^&*()_+ in JavaScript. So, I am trying to implement it for the password validation, and I followed some documentation about regular expressions I found online, but it did not work correctly only for symbols (it worked for numbers and alphabet characters)

The function below is the sample code of what I used on my web application. When I type a password on the web application, this function always returns false even if I put in symbols.

function valid_password(password) {
    var sym = new RegExp('[ @#$%^&_*-+=[]{}()?]+');
    if (sym.test(password)) {
        return true;
    } else {
        return false;
    }
}

Solution

  • You need to escape special characters in your regex, such as [, ], -. Also, for better performance avoid compiling a new regex each time you call the function, which is only needed when you want to compose a pattern based on variable input. The .test() returns true or false, e.g. no need for the if/else.

    Here is the function fixed:

    function hasSymbol(password) {
        return /[ @#$%^&_*\-+=\[\]{}()\?]/.test(password);
    }
    
    [ 'abc', 'a@z', 'a z', '+++' ].forEach(password => {
      let check = hasSymbol(password);
      console.log(password, '=>', check);
    });

    Output:

    abc => false
    a@z => true
    a z => true
    +++ => true
    

    This tests for a single symbol in a password. You might want to test for at least a number of symbols. You can do that with a positive lookahead. Here is an example for at least 3 symbols:

    function hasThreeSymbols(password) {
        return /^(?=(?:.*?[ @#$%^&_*\-+=\[\]{}()\?]){3,})/.test(password);
    }
    
    [ 'abc', 'a@z', 'a z', '+++', 'a#b$c', 'a#b$c^d' ].forEach(password => {
      let check = hasThreeSymbols(password);
      console.log(password, '=>', check);
    });

    Output:

    abc => false
    a@z => false
    a z => false
    +++ => true
    a#b$c => false
    a#b$c^d => true
    

    Explanation of regex:

    • ^ -- anchor at start of string
    • (?= -- positive lookahead start
      • (?: -- non-capture group start
        • .*? -- non-greedy scan for:
        • [ @#$%^&_*\-+=\[\]{}()\?] -- a single symbol
      • ) -- non-capture group end
      • {3,} -- require 3+ occurrences of previous pattern, e.g. capture group
    • ) -- positive lookahead end

    To learn more about regex: https://twiki.org/cgi-bin/view/Codev/TWikiPresentation2018x10x14Regex