I want to identify strings that are made up exclusively of same-length character groups. Each one of these groups consists of at least two identical characters. So, here are some examples:
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
@ilkkachu: Thanks for your remark concerning the repetition of the same character group. I added the example above. Yes, I want the last sample to be tested as true: a string made up of the two letter groups aa, bb, bb, cc
.
Is there a simple way to apply this condition-check on a string using regular expressions and JavaScript?
My first attempt was to do something like
var strarr=['aabbcc','abbccaa','xxxrrrruuu',
'xxxxxfffff','aa','negative'];
var rx=/^((.)\2+)+$/;
console.log(strarr.map(str=>str+': '+!!str.match(rx)).join('\n'));
It does look for groups of repeated characters but does not yet pay attention to these groups all being of the same length, as the output shows:
aabbcc: true
abbccaa: false
xxxrrrruuu: true // should be false!
xxxxxfffff: true
aa: true
aabbbbcc: true
negative: false
How do I get the check to look for same-length character groups?
To find whether a string has all the same characters. Traverse the whole string from index 1 and check whether that character matches the first character of the string or not. If yes, then match until string size. If no, then break the loop.
As you know, the best way to find the length of a string is by using the strlen() function.
To calculate the length of a string in Python, you can use the built-in len() method. It takes a string as a parameter and returns an integer as the length of that string. For example len(“educative”) will return 9 because there are 9 characters in “educative”.
If there are odd number of characters in the string, we ignore the middle character and check for lapindrome. For example gaga is a lapindrome, since the two halves ga and ga have the same characters with same frequency. Also, abccab, rotor and xyzxy are a few examples of lapindromes.
You can check if a string only contains certain characters result by using Sets. Declare a set using the characters you want to allow. You can also use regexes for the same result. For matching only 1, 2, 3 and 4, we can call the re.match (regex,...
The length of the given string is always greater than 1 and the character sequence must have at least one repetition. I have created the below function:
For example, in the following string of text, there are 74 instances that match the above classifications of a character, so the length of this string of text would be 74 characters: "Use the string length calculator for your convenience & to save time!"
Assume the string S has length N and is made of duplicates of the substring s, then the length of s divides N. For example, if S has length 15, then the substring has length 1, 3, or 5. Let S be made of (p*q) copies of s.
To get all the groups of the same character has an easy regex solution:
/(.)\1*/g
Just repeating the backreference \1
of the character in capture group 1.
Then just check if there's a length in the array of same character strings that doesn't match up.
Example snippet:
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)});
ECMAScript 6 version with fat arrows (doesn't work in 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;
}
Or using exec instead of match, which should be faster for huge strings.
Since it can exit the while loop as soon a different length is found.
But this has the disadvantage that this way it can't get the minimum length of ALL the lengths before comparing them.
So those with the minimum length at the end can't be found as OK this way.
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)});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With