1

I am trying to use regex in JavaScript to verify if a given password has alphabetic, numeric, and a special character. However, everything I have tried doesn't work

I have tried using

/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@"#%$&])[A-Za-z0-9!@"#%$&]{8,30}$/gm

and creating separate regex variables for alphabetic, numeric, and special characters:

let alpha = /^[A-Za-z]+$/i
let numer = /^[0-9]+$/i
let special = /^[!@#$%^&*(),.?;":{}|<>']/i

Picture of My Code

When I log the password.match(regex) to the console I always see null

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
PWenzel99
  • 15
  • 3
  • Can you add the code to the question instead of an image? – The fourth bird Oct 18 '19 at 16:37
  • I know this is unrelated but be careful when using regex to validate things like passwords, make sure to set a timeout or you'll most likely be exposed to ReDoS attacks. – Darkly Oct 18 '19 at 16:45

3 Answers3

0

Try this:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,15}$

This is from a post a long time ago. There are probably others as well. A simple search of SO will find more examples.1

Here is a visualisation of the regular expression:

Regular expression visualization

Debuggex Demo

Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
nopuck4you
  • 1,730
  • 14
  • 20
  • Hi @nopuck4you, I hope you don't mind me adding the visualisation to your post - I didn't want to start a separate answer for it, as you have already posted the important stuff yourself! – Carsten Massmann Oct 18 '19 at 16:40
0

I would personally go for separate regexes, the issue with your current regexes is that you have ^ at the start and $ at the end. Which means that the password must only contain [A-Za-z] from start to finish. Then you check if the password only contains [0-9] from start to finish.

const regexes = {
  alpha:   /[A-Za-z]/,
  number:  /[0-9]/,
  special: /[!@#$%^&*(),.?;":{}|<>']/,
  length:  /^.{8,30}$/
};

["dgXHUYuDdp", "zMv4qQfZj3", "4JXyrsq!J0", "a5Z!"].forEach(password => {
  let valid = Object.values(regexes).every(regex => password.match(regex));

  console.log(
    "password: " + JSON.stringify(password) + "\n" +
    "valid: " + valid
  );
});
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
0

While I suspect it may be possible to write a regex which will do position/seuqnce independent matching, my head hurts just thinking about. So even if I could work out a way of doing it, I would not implement it - code needs to be readable and parseable by human beings. Looking at what you have presented here, I think I'm a lot more familiar with regexes than you are - so even more reason not to do this.

Your alpha / numer / special regexes will only match a string containing letters, numbers or special characters, not a mixture. If you change them thus, then you can check for a match of all three (and escape the meta characters in the special regex):

let alpha = /[A-Za-z]/i;
let numer = /[0-9]/;
let special = /[!@#$%\^&*(),\.?;":{}|<>\']/;
if (password.match(alpha) && password.match(numer) && password.match(speicial)) {
symcbean
  • 47,736
  • 6
  • 59
  • 94