简体   繁体   中英

Javascript check three ascending letters and numbers in a string

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'));

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 complication, 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) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM