Jump to content

regex is making browser unresponsive


charan

Recommended Posts

My HTML page is having password input field when I try to input values to the password input field then the page becomes unresponsive after entering more than 30 to 40 characters. Below is the code which I am using. This issue I am having in all web browsers. Even if I change the minimum length and all other like lower, upper, number and symbol value to 50 then also the same problem persist. I am new to javascript, Kindly do the needful.

What I have observed here is the regex ( new RegExp('(?:[0-9].*){' + 199 + '}', 'g')  ) used is causing this issue. If I change the value from 199 to 15 then it will work fine.

 

    <!DOCTYPE html>
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    /* Style all input fields */
    input {
      width: 100%;
      padding: 12px;
      border: 1px solid #ccc;
      border-radius: 4px;
      box-sizing: border-box;
      margin-top: 6px;
      margin-bottom: 16px;
    }

    /* Style the submit button */
    input[type=submit] {
      background-color: #4CAF50;
      color: white;
    }

    /* Style the container for inputs */
    .container {
      background-color: #f1f1f1;
      padding: 20px;
    }

    /* The message box is shown when the user clicks on the password field */
    #message {
      display:none;
      background: #f1f1f1;
      color: #000;
      position: relative;
      padding: 20px;
      margin-top: 10px;
    }

    #message p {
      padding: 10px 35px;
      font-size: 18px;
    }

    /* Add a green text color and a checkmark when the requirements are right */
    .valid {
      color: green;
    }

    .valid:before {
      position: relative;
      left: -35px;
      content: "✔";
    }

    /* Add a red text color and an "x" when the requirements are wrong */
    .invalid {
      color: red;
    }

    .invalid:before {
      position: relative;
      left: -35px;
      content: "✖";
    }
    </style>
    </head>
    <body>

    <p>Try to submit the form.</p>

    <div class="container">
      <form action="/action_page.php">
        <label for="usrname">Username</label>
        <input type="text" id="usrname" name="usrname" required>

        <label for="psw">Password</label>
        <input type="password" id="psw" name="psw" required>
        
        <input type="submit" value="Submit">
      </form>
    </div>

    <div id="message">
      <h3>Password must contain the following:</h3>
      <p id="letter" class="invalid">199 <b>lowercase</b> letter</p>
      <p id="capital" class="invalid">199 <b>capital (uppercase)</b> letter</p>
      <p id="number" class="invalid">199 <b>number</b></p>
      <p id="length" class="invalid">Minimum <b>199 characters</b></p>
    </div>
    				
    <script>
    var myInput = document.getElementById("psw");
    var letter = document.getElementById("letter");
    var capital = document.getElementById("capital");
    var number = document.getElementById("number");
    var length = document.getElementById("length");

    // When the user clicks on the password field, show the message box
    myInput.onfocus = function() {
      document.getElementById("message").style.display = "block";
    }

    // When the user clicks outside of the password field, hide the message box
    myInput.onblur = function() {
      document.getElementById("message").style.display = "none";
    }

    // When the user starts to type something inside the password field
    myInput.onkeyup = function() {
      // Validate lowercase letters
      var lowerCaseLetters = new RegExp('(?:[a-z].*){' + 199 + '}', 'g')
      if(myInput.value.match(lowerCaseLetters)) {  
        letter.classList.remove("invalid");
        letter.classList.add("valid");
      } else {
        letter.classList.remove("valid");
        letter.classList.add("invalid");
      }
      
      // Validate capital letters
      var upperCaseLetters = new RegExp('(?:[A-Z].*){' + 199 + '}', 'g')
      if(myInput.value.match(upperCaseLetters)) {  
        capital.classList.remove("invalid");
        capital.classList.add("valid");
      } else {
        capital.classList.remove("valid");
        capital.classList.add("invalid");
      }

      // Validate numbers
      var numbers = new RegExp('(?:[0-9].*){' + 199 + '}', 'g')
      if(myInput.value.match(numbers)) {  
        number.classList.remove("invalid");
        number.classList.add("valid");
      } else {
        number.classList.remove("valid");
        number.classList.add("invalid");
      }
      
      // Validate length
      if(myInput.value.length >= 199) {
        length.classList.remove("invalid");
        length.classList.add("valid");
      } else {
        length.classList.remove("valid");
        length.classList.add("invalid");
      }
    }
    </script>

    </body>
    </html>

 

Edited by charan
unwanted code got inserted.
Link to comment
Share on other sites

What exactly are you trying to match with that regular expression? It looks unnecessarily complicated. There isn't a reason to use the RegExp constructor here either.

What you're checking for with that expression is 199 strings of any length, even empty strings count, containing only the specified characters

You just need to check for a minimum of one of each type of character.

var val = myInput.value;

// Check for lowercase letters
var lowerCaseLetters = /[a-z]/;
if(lowerCaseLetters.test(val)) {  
  letter.classList.remove("invalid");
  letter.classList.add("valid");
} else {
  letter.classList.remove("valid");
  letter.classList.add("invalid");
}

// Check for uppercase letters
var upperCaseLetters = /[A-Z]/;
if(upperCaseLetters.test(val)) {  
  capital.classList.remove("invalid");
  capital.classList.add("valid");
} else {
  capital.classList.remove("valid");
  capital.classList.add("invalid");
}

// Check for numbers
var numbers = /[0-9]/;
if(numbers.test(val)) {  
  number.classList.remove("invalid");
  number.classList.add("valid");
} else {
  number.classList.remove("valid");
  number.classList.add("invalid");
}

if(val.length >= 199) {
  length.classList.remove("invalid");
  length.classList.add("valid");
} else {
  length.classList.remove("valid");
  length.classList.add("invalid");
}

 

Link to comment
Share on other sites

4 minutes ago, Ingolme said:

What exactly are you trying to match with that regular expression? It looks unnecessarily complicated. There isn't a reason to use the RegExp constructor here either.

What you're checking for with that expression is 199 strings of any length, even empty strings count, containing only the specified characters

You just need to check for a minimum of one of each type of character.


var val = myInput.value;

// Check for lowercase letters
var lowerCaseLetters = /[a-z]/;
if(lowerCaseLetters.test(val)) {  
  letter.classList.remove("invalid");
  letter.classList.add("valid");
} else {
  letter.classList.remove("valid");
  letter.classList.add("invalid");
}

// Check for uppercase letters
var upperCaseLetters = /[A-Z]/;
if(upperCaseLetters.test(val)) {  
  capital.classList.remove("invalid");
  capital.classList.add("valid");
} else {
  capital.classList.remove("valid");
  capital.classList.add("invalid");
}

// Check for numbers
var numbers = /[0-9]/;
if(numbers.test(val)) {  
  number.classList.remove("invalid");
  number.classList.add("valid");
} else {
  number.classList.remove("valid");
  number.classList.add("invalid");
}

if(val.length >= 199) {
  length.classList.remove("invalid");
  length.classList.add("valid");
} else {
  length.classList.remove("valid");
  length.classList.add("invalid");
}

 

 

5 minutes ago, Ingolme said:

What exactly are you trying to match with that regular expression? It looks unnecessarily complicated. There isn't a reason to use the RegExp constructor here either.

What you're checking for with that expression is 199 strings of any length, even empty strings count, containing only the specified characters

You just need to check for a minimum of one of each type of character.


var val = myInput.value;

// Check for lowercase letters
var lowerCaseLetters = /[a-z]/;
if(lowerCaseLetters.test(val)) {  
  letter.classList.remove("invalid");
  letter.classList.add("valid");
} else {
  letter.classList.remove("valid");
  letter.classList.add("invalid");
}

// Check for uppercase letters
var upperCaseLetters = /[A-Z]/;
if(upperCaseLetters.test(val)) {  
  capital.classList.remove("invalid");
  capital.classList.add("valid");
} else {
  capital.classList.remove("valid");
  capital.classList.add("invalid");
}

// Check for numbers
var numbers = /[0-9]/;
if(numbers.test(val)) {  
  number.classList.remove("invalid");
  number.classList.add("valid");
} else {
  number.classList.remove("valid");
  number.classList.add("invalid");
}

if(val.length >= 199) {
  length.classList.remove("invalid");
  length.classList.add("valid");
} else {
  length.classList.remove("valid");
  length.classList.add("invalid");
}

 

 

5 minutes ago, Ingolme said:

What exactly are you trying to match with that regular expression? It looks unnecessarily complicated. There isn't a reason to use the RegExp constructor here either.

What you're checking for with that expression is 199 strings of any length, even empty strings count, containing only the specified characters

You just need to check for a minimum of one of each type of character.


var val = myInput.value;

// Check for lowercase letters
var lowerCaseLetters = /[a-z]/;
if(lowerCaseLetters.test(val)) {  
  letter.classList.remove("invalid");
  letter.classList.add("valid");
} else {
  letter.classList.remove("valid");
  letter.classList.add("invalid");
}

// Check for uppercase letters
var upperCaseLetters = /[A-Z]/;
if(upperCaseLetters.test(val)) {  
  capital.classList.remove("invalid");
  capital.classList.add("valid");
} else {
  capital.classList.remove("valid");
  capital.classList.add("invalid");
}

// Check for numbers
var numbers = /[0-9]/;
if(numbers.test(val)) {  
  number.classList.remove("invalid");
  number.classList.add("valid");
} else {
  number.classList.remove("valid");
  number.classList.add("invalid");
}

if(val.length >= 199) {
  length.classList.remove("invalid");
  length.classList.add("valid");
} else {
  length.classList.remove("valid");
  length.classList.add("invalid");
}

 

Yes, Correct this will work and onkeyup function will only validate for one small letter, one upper case letter, one special char and one digit.

but what I wanted is to validate all categories to 199 length instead of one. that is what is my requirement is and that's why I have used the below regex.

var lowerCaseLetters = new RegExp('(?:[a-z].*){' + 199 + '}', 'g')
Link to comment
Share on other sites

I'm not sure what your requirement is. How many lowercase characters does the password need? How many uppercase characters does it need? Does the order matter?

Link to comment
Share on other sites

There isn't a regular expression that will count characters if they're not consecutive. You'll have to match the string and then count the number of matches instead.

var lowercase = myInput.value.match(/a-z/g);
var uppercase = myInput.value.match(/A-Z/g);
var digits = myInput.value.match(/0-9/g);

var numLowerCase = lowercase ? lowercase.length : 0;
var numUpperCase = uppercase ? uppercase.length : 0;
var numDigits = digits ? digits.length : 0;

if(numLowercase < 199) {
  // Not enough lowercase letters
}

if(numUppercase < 199) {
  // Not enough uppercase letters
}

if(numDigits < 199) {
  // Not enough digits
}


 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...