0

I want to reject user input if it contains 2 sequential numbers or characters ,for example 1234,jkl, zyxw and if it contains more than 1 same numbers or characters like aaer,0000,aabb,pp22. Thank you for insights. I have regex for the second one but dont know how to combine the two expressions:

"([a-zA-Z0-9])\\1{1,}"
Rohit
  • 211
  • 1
  • 5
  • 14
  • Your first requirement will be difficult to handle with pure regex. A backreference won't help much (from what I can see). – Tim Biegeleisen Apr 27 '18 at 06:48
  • This is difficult enough to do without regex (given that you have multiple conditions to handle and back-references as well), I don't think regex is what you should be looking for. – gurvinder372 Apr 27 '18 at 06:52
  • Is possible to do it in javascript, I can use regex for one check and javascript for the other. – Rohit Apr 27 '18 at 07:07
  • @Rohit I missed the _"no more than 2"_ part, and have now updated my answer. – Asons Apr 27 '18 at 08:26
  • Check https://stackoverflow.com/a/16252097/2064981. Could be a start for you. – SamWhan Apr 27 '18 at 08:59

2 Answers2

2

Doing this in regex is neither sound nor practical. However, you can easily check if your input contains a sequential (abc.. or cba) pattern using code like that:

function isSequencial(input) {

  var numpattern = '0123456789012345789'; // match ascending/descending sequence of numbers.
  var charpattern = 'ABCDEFGHIJKLMNOPQRSTUVWXYZYXWVUTSRQPONMLKJIHGFEDCBA'; // match ascending/descending sequence of letters.

  for (var i = 0; i < input.length-1; i++) {
    var shard = input.substring(i,i+2);
    if(numpattern.indexOf(shard) != -1) {
      console.log('sequential number pattern detected: ' + shard);
      return true;
    }
    if (charpattern.indexOf(shard.toUpperCase()) != -1) {
      console.log('sequential letter pattern detected: ' +shard);
      return true;
    } 
  }
  return false;
}

console.log("isSequencial(a234):" + isSequencial("a234"));
console.log("isSequencial(azyx):" + isSequencial("azyx"));
console.log("isSequencial(xbc):" + isSequencial("xbc"));
console.log("isSequencial(2435):" + isSequencial("2435"));

This code can be optimized but is easy to understand and maintain since it does not try to do multiple things at once. You should be able to combine this with your existing approach.

wp78de
  • 18,207
  • 7
  • 43
  • 71
  • The major issue with this is, it won't be able to deal with case letters, as it turns them all into upper case. Also, 2 in sequence is allowed, which your catch (and it shouldn't). – Asons Apr 27 '18 at 15:15
1

The simplest solution for your first requirement would be to parse it, as with a regex it will be not that easy to set up, if at all possible.

Here I used charCodeAt (and check for both sequence/equal and duplicates characters)

var input1 = "1543abc3";
var input2 = "cba23DEf";
var input3 = "ba2354cd";


console.log('test 1');
testit(input1.split(''));

console.log('test 2');
testit(input2.split(''));

console.log('test 3');
testit(input3.split(''));


function testit (arr) {

  var prev = arr[0].charCodeAt(0) + 1, prev2 = -1;

  for (var i = 1; i < arr.length; i++) {
  
    var arritem = arr[i].charCodeAt(0);
  
    if ( (arritem == prev && arritem == (prev2+1)) ||    // abc
         (arritem == (prev-2) && arritem == (prev2-3))   // cba
       ) {
      console.log(' - sequence, more than 2: ', arr[i-2], arr[i-1], arr[i] );
      //return false;
    }
    if (arr.indexOf(arr[i-1],i) > -1) {
      console.log(' - duplicate, more than 1: ', arr[i-1] );
      //return false;
    }
    
    prev2 = prev;
    prev = arr[i].charCodeAt(0) + 1;
  }
  
  //return true;  
}
Asons
  • 84,923
  • 12
  • 110
  • 165