如何检查字符串是否仅由相同长度的字符组组成?

car*_*10m 20 javascript regex

我想识别由相同长度的字符组组成的字符串.这些组中的每一个都包含至少两个相同的字符.所以,这里有一些例子:

aabbcc          true
abbccaa         false
xxxrrrruuu      false (too many r's)
xxxxxfffff      true
aa              true (shortest possible positive example)
aabbbbcc        true // I added this later to clarify my intention
Run Code Online (Sandbox Code Playgroud)

@ilkkachu:感谢您关于重复相同角色组的评论.我添加了上面的例子.是的,我希望将最后一个样本测试为true:由两个字母组组成的字符串aa, bb, bb, cc.

是否有一种简单的方法可以使用正则表达式和JavaScript对字符串应用此条件检查?

我的第一次尝试是做类似的事情

var strarr=['aabbcc','abbccaa','xxxrrrruuu',
            'xxxxxfffff','aa','negative'];
var rx=/^((.)\2+)+$/;

console.log(strarr.map(str=>str+': '+!!str.match(rx)).join('\n'));
Run Code Online (Sandbox Code Playgroud)

确实查找重复字符的组,但不关注这些群体的所有作为的长度相同,如输出所示:

aabbcc: true
abbccaa: false
xxxrrrruuu: true // should be false!
xxxxxfffff: true
aa: true
aabbbbcc: true
negative: false
Run Code Online (Sandbox Code Playgroud)

如何检查以查找相同长度的字符组?

Luk*_*rms 9

要获得相同角色的所有组,可以使用简单的正则表达式解决方案:

/(.)\1*/g
Run Code Online (Sandbox Code Playgroud)

只需重复\1捕获组1中角色的反向引用.

然后检查数组中是否存在不匹配的相同字符串的长度.

示例代码段:

function sameLengthCharGroups(str)
{
     if(!str) return false;
     let arr = str.match(/(.)\1*/g) //array with same character strings
                  .map(function(x){return x.length}); //array with lengths
     let smallest_length = arr.reduce(function(x,y){return x < y ? x : y});
     if(smallest_length === 1) return false;
     return arr.some(function(n){return (n % smallest_length) !== 0}) == false;
}

console.log("-- Should be true :");
let arr = ['aabbcc','xxxxxfffff','aa'];
arr.forEach(function(s){console.log(sameLengthCharGroups(s)+' : '+ s)});

console.log("-- Should also be true :");
arr = ['aabbbbcc','224444','444422',
       '666666224444666666','666666444422','999999999666666333'];
arr.forEach(function(s){console.log(sameLengthCharGroups(s)+' : '+ s)});

console.log("-- Should be false :");
arr = ['abbcc','xxxrrrruuu','a','ab','',undefined];
arr.forEach(function(s){console.log(sameLengthCharGroups(s)+' : '+ s)});
Run Code Online (Sandbox Code Playgroud)

带有胖箭头的ECMAScript 6版本(在IE中不起作用)

function sameLengthCharGroups(str)
{
     if(!str) return false;
     let arr = str.match(/(.)\1*/g)
                  .map((x) => x.length);
     let smallest_length = arr.reduce((x,y) => x < y ? x : y);
     if(smallest_length === 1) return false;
     return arr.some((n) => (n % smallest_length) !== 0) == false;
}
Run Code Online (Sandbox Code Playgroud)

或者使用exec代替匹配,对于大字符串应该更快.
因为它可以在找到不同长度后立即退出while循环.
但这样做的缺点是,在比较它们之前,它无法获得所有长度的最小长度.
所以那些最后长度最小的人就不会这样.

function sameLengthCharGroups(str)
{
     if(!str) return false;
     const re = /(.)\1*/g;
     let m, smallest_length;
     while(m = re.exec(str)){
       if(m.index === 0) {smallest_length = m[0].length}
       if(smallest_length > m[0].length && smallest_length % m[0].length === 0){smallest_length = m[0].length}
       if(m[0].length === 1 || 
              // m[0].length !== smallest_length
             (m[0].length % smallest_length) !== 0
         ) return false;
     }
     return true;
}

console.log("-- Should be true :");
let arr = ['aabbcc','xxxxxfffff','aa'];
arr.forEach(function(s){console.log(sameLengthCharGroups(s)+' : '+ s)});

console.log("-- Should also be true :");
arr = ['aabbbbcc','224444','444422',
       '666666224444666666','666666444422','999999999666666333'];
arr.forEach(function(s){console.log(sameLengthCharGroups(s)+' : '+ s)});

console.log("-- Should be false :");
arr = ['abbcc','xxxrrrruuu','a','ab','',undefined];
arr.forEach(function(s){console.log(sameLengthCharGroups(s)+' : '+ s)});
Run Code Online (Sandbox Code Playgroud)


Mát*_*nka 5

这是一个在线性时间运行的:

function test(str) {
    if (str.length === 0) return true;

    let lastChar = str.charAt(0);
    let seqLength = 1;
    let lastSeqLength = null;
    for (let i = 1; i < str.length; i++) {
        if (str.charAt(i) === lastChar) {
            seqLength++;
        }
        else if (lastSeqLength === null || seqLength === lastSeqLength) {
            lastSeqLength = seqLength;
            seqLength = 1;
            lastChar = str.charAt(i);
        }
        else {
            return false;
        }
    }
    return (lastSeqLength === null || lastSeqLength === seqLength);
}
Run Code Online (Sandbox Code Playgroud)