How to find words with only/more specified letters using preg_grep in array?

511 views Asked by At

I have sample function for searching words from array with specified letters:

public static function getWords($words, $specifed_letters) 
{ 
    $pattern = is_array($specifed_letters) ? '/[' . implode("", 
    $specifed_letters) . ']/u' : '/[' .$specifed_letters. ']/u';
    $result = preg_grep($pattern, $array_words);
    return $result;
}

Example usage:

$words = ["apple", "sample", "app", "тоҷик", "отабек", "баҳодурбек"];
$result = getWords($words, $letters = ['l', 's']);

This example will return words: apple, sample. Because in this words have letters "l" or "s".

How I can search words where have all specifed letters in word?

For example if I add to specifed letters "app" then from words array must be return words: app, apple.

And how search word with only specifed letters. For example I will write word "app" in shuffled variant "pap". And how I can get on result only word "app" without "apple"?

2

There are 2 answers

2
The fourth bird On BEST ANSWER

You could split the word characters to an array and loop them, and split the characters from the specified string to an array.

If one of the word characters occur in the characters from the specified string array, remove the character from both arrays.

Once the loop is done, verify that there are no more characters left in the characters from the specified string array.

$words = ["apple", "sample", "app", "justappgg", "тоҷик", "отабек", "баҳодурбек", "APELCIN", "API", "pap"];
mb_internal_encoding("UTF-8");

foreach ($words as $word) {
    $wordSplit = preg_split('//u', $word, null, PREG_SPLIT_NO_EMPTY);
    $strSplit = preg_split('//u', $str, null, PREG_SPLIT_NO_EMPTY);
    $wordSplit = array_filter($wordSplit, function ($x) use (&$strSplit) {
        if (in_array(strtolower($x), array_map('strtolower', $strSplit), true)) {
            $pos = array_search(strtolower($x), array_map('strtolower', $strSplit), true);
            unset($strSplit[$pos]);
            return false;
        }
        return true;
    });
    if (count($strSplit) === 0) {
        echo "$word contains all letters of $str" . PHP_EOL;
    }
}

Demo

5
Andreas On

You can use preg_grep.
If you implode the letters inside [] in the regex pattern it should look for the letter and return the item if found.

$words = ["apple", "sample", "app", "тоҷик", "отабек", "баҳодурбек"];
$letters = ['l', 's'];

$res = preg_grep("/[" . implode("", $letters) . "]/", $words); // pattern = "/[ls]/"
var_dump($res);

https://3v4l.org/UZTYZ

EDIT
But this part of your question: And how search word with only specifed letters. For example I will write word "app" in shuffled variant "pap". And how I can get on result only word "app" without "apple"?
Is the exact opposite of the first part where you wanted a very loose search.
Are you expecting one loose and one exact result array?


You can do the exact match by splitting the strings and sorting the letters (in the array).
Then check if the arrays match each other. If they do, then it's an exact match.

$words = ["apple", "sample", "app", "тоҷик", "отабек", "баҳодурбек"]; 
$find = "pap";

$find = str_split($find);
sort($find);
foreach($words as $word){
    $temp = str_split($word);
    sort($temp);
    if($temp == $find){
        echo "match " . $word . "\n";
    }
}

https://3v4l.org/WbTUK