Search code examples
phpstringsearchsubstring

Detecting combination of letters in string in php


I have a certain not to short sting that are actually collection of flags/parameters (generated from a loop of products, but it does not matter).

Say:

aaaaaaaoooooreioopppdffdssds
yxxxsasadddddaaaaddaadadadad
oppppppassaaaaawwwwwww

And so on.

I need to detect if inside this longer string there is combination of certain flags.

For example:

aaaaa (5* letter a)
xyy (1*x + 2*y)
opp (1*o + 2*pp)

Basically if the longer sting contains 5 letters "a" then statement should be as true. It would be really easy if the was only situation like this yyyyaaaaaaxxxx (contains substring aaaaa). But the thing is that 5 "a" letters can be completely disconnected from each other like yayaxayataya (and it's just one example. There can be very many required flags combinations).

My guess is preg_match could do it - could someone tell me how?


Solution

  • If you don't need this in an environment where you can only use regex - then I would go with

    array_count_values(mb_str_split('aaaaaaaoooooreioopppdffdssds'));
    

    That will give you the count for each character (multibyte-safe), so all you have to do now is check in the resulting array, if there is an entry for that character you are looking for, and if that count is equal to (or higher, if that is not to be excluded) the one you are looking for.

    And if xyy is your "input" for which characters you need to find - then apply the same two functions to that as well, then you get an array that gives you the (minimum) counts you need to look for, so you can simply loop over that to perform your test.

    function checkLetters($letters, $teststring) {
        $inputLetterCounts = array_count_values(mb_str_split($letters));
        $letterCounts = array_count_values(mb_str_split($teststring));
        foreach($inputLetterCounts as $inputLetter => $count) {
            if(!isset($letterCounts[$inputLetter]) ||
               $letterCounts[$inputLetter] < $count) {
                return false;
            }
        }
        return true;
    }
    var_dump(
        checkLetters('xxy', 'aaaaaaoooooreioopppdffdssds'), // false
        checkLetters('xxy', 'aaaaxaaoyooorexoopppdffdssds'), // true
    );
    

    Whether you want to check the count for < or !=, you decide - depends on whether you want to allow more occurrences of a character, or only that specific number.