最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

regex - Javascript check three ascending letters and numbers in a string - Stack Overflow

programmeradmin1浏览0评论

I am trying to figure it out how can I check if a string has three ascending letters and/or number in a string. For example, if a string has "manabcrt" then there is "abc" or "castle567", there is "567" in the string or "castlexyzand789" it has "xyz" and 789 ... so I want to check for that. I find this one fiddle but it is doing for the repeating letters.

This is the code from the fiddle:

var inputs = [
'helloworld',
'hellloworld',
'aaabc',
'abcddd',
'bbabba'];

var violators = [];
inputs.forEach(function(input) {
if (/(.)\1\1/.test(input)) {
    violators.push(input);
}});
alert("VIOLATORS:\n" + violators.join('\n'));

I am trying to figure it out how can I check if a string has three ascending letters and/or number in a string. For example, if a string has "manabcrt" then there is "abc" or "castle567", there is "567" in the string or "castlexyzand789" it has "xyz" and 789 ... so I want to check for that. I find this one fiddle but it is doing for the repeating letters.

This is the code from the fiddle:

var inputs = [
'helloworld',
'hellloworld',
'aaabc',
'abcddd',
'bbabba'];

var violators = [];
inputs.forEach(function(input) {
if (/(.)\1\1/.test(input)) {
    violators.push(input);
}});
alert("VIOLATORS:\n" + violators.join('\n'));
Share Improve this question asked Jan 31, 2018 at 15:21 jeewanjeewan 1,6055 gold badges24 silver badges41 bronze badges 12
  • 4 you will probably over-plexify your problem by using a regex, the situation is different than a repetition. I suggest you give a try with loops instead.. – Kaddath Commented Jan 31, 2018 at 15:24
  • Only 3 letters? – Srdjan M. Commented Jan 31, 2018 at 15:26
  • 1 yes only three letter and/or number. This is for the password validation while creating a new account. So the user can not have password like "castle123" or "javaxyz" or "p456ythonjkl" – jeewan Commented Jan 31, 2018 at 15:27
  • I agree with @Kaddath. Try it with looping, and post your code here if you need help with it. – freginold Commented Jan 31, 2018 at 15:28
  • 1 When you say that you want an ascending character sequence, do you mean that they must be strictly 1 position after the other, or do a sequence like acd is also valid? – Pedro Corso Commented Jan 31, 2018 at 15:38
 |  Show 7 more ments

6 Answers 6

Reset to default 5

You could check the values by counting the ascending pairs.

var array = ['manabcrt', 'castle567', , 'castlexyzand789', 'helloworld', 'hellloworld', 'aaabc', 'abcddd', 'bbabba'],
    check = array.filter(s => {
        var v = 1;
        return [...s].some((c, i, a) => {
            v *= parseInt(c, 36) + 1 === parseInt(a[i + 1], 36);
            return ++v === 3;
        });
    });
    
console.log(check);

Some adjustment to the cases '90' and for not including '9a'

var array = ['zab', '901', '9ab', 'manabcrt', 'castle567', , 'castlexyzand789', 'helloworld', 'hellloworld', 'aaabc', 'abcddd', 'bbabba'],
    check = array.filter(s => {
        var v = 1;
        return [...s].some((c, i, a) => {
            var l = parseInt(c, 36),
                r = parseInt(a[i + 1], 36);

            v *= l + 1 === r && l !== 9 && r !== 10 || l === 9 && r === 0 || l === 35 && r === 10;
            return ++v === 3;
        });
    });
    
console.log(check);

It's a dull exercise but you are probably best off spelling out all possible triplets ( 10 + 2*26 ) in your regex, testing for their presence:

(012|123|234|345|456|567|678|789|890|901|abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz|yza|zab|ABC|BCD|CDE|DEF|EFG|FGH|GHI|HIJ|IJK|JKL|KLM|LMN|MNO|NOP|OPQ|PQR|QRS|RST|STU|TUV|UVW|VWX|WXY|XYZ|YZA|ZAB)

Of course, this approach fails on non-latin characters.

See the live demo (Regex101).

To use it in your code, replace

if (/(.)\1\1/.test(input)) {
    violators.push(input);
}});

with

if (/(012|123|234|345|456|567|678|789|890|901|abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz|yza|zab|ABC|BCD|CDE|DEF|EFG|FGH|GHI|HIJ|IJK|JKL|KLM|LMN|MNO|NOP|OPQ|PQR|QRS|RST|STU|TUV|UVW|VWX|WXY|XYZ|YZA|ZAB)/.test(input)) {
    violators.push(input);
}});

With Array.filter() and String.charCodeAt() functions:

var inputs = ['manabcrt', 'castle345', 'helloworld', 'abcddd', 'password'],
    invalid_items = inputs.filter(function(w){
        var len = w.length;            // word length
        for (i=0; i<=len-3; i+=3) {    // iterating over 3-char sequences
            var char_code = w[i].charCodeAt(0);
            if (w[i+1].charCodeAt(0) - char_code == 1 &&
                w[i+2].charCodeAt(0) - char_code == 2) {
                return true;
            }
        }
        return false;
    });

console.log(invalid_items);

Performance test result:

For any substring length

function containsNAscLetters(input, n){
    for(var j = 0; j<=input.length-n; j++){
        var buf = input.substring(j, j+n);
        if (buf.split('').sort().join('').toString()===buf) return buf;
    }
    return null;
}

containsNAscLetters("avfabc", 3)

Without too much plication, you could do it with a for loop, even allowing for sequences with length greater than 3:

function hasAscSequence(str, limit){
  var count = 0;
  for(var i = 1; i<str.length;i++){
    if(str.charCodeAt(i) - str.charCodeAt(i-1) == 1) count++;
    else count = 0;
    if(count == limit-1) return true
  }
  return false;
}

var inputs = [
'helloworld',
'hellloworld',
'aaabc',
'abcddd',
'bbabba'];

console.log(inputs.filter(x=>!hasAscSequence(x, 3)));

In the case that you also don't want to match 3 descending chars in a row as well:

let inputs = [
    'helloworld',
    'hellloworld',
    'aaabc',
    'abcddd',
    'bbabba',
    'cbaheop'
  ],
  valid = [];

inputs.forEach((password) => {
  let passValid = true;
    for (i = 0; i < password.length - 2; i++) {
      let currentChar = password.charCodeAt(i),
        oneCharLater = password.charCodeAt(i + 1),
        twoCharLater = password.charCodeAt(i + 2);

      if ((currentChar + 1 === oneCharLater && currentChar + 2 === twoCharLater) || (currentChar - 1 === oneCharLater && currentChar - 2 === twoCharLater)) {
        passValid = false;
        break;
      }
    }
  if (passValid) {
    valid.push(password)
  }
})

console.log(valid)

发布评论

评论列表(0)

  1. 暂无评论