Filter out strings that are short or that are outside the alphabet of a language I wrote this function to remove from the array those words that are less than n values. More precisely, I updated my old function and added some functionality. Since I am a beginner in this programming language and so I could in my code allow for various illogical errors: Old version of my function:

$words = array("ӯтар","ӯро","ӯт","ғариб","афтода","даст", "ра", "I","Hello", "World"); // Simple array for using

function delValByLessOld($array)
{
    return preg_grep('~\A[^qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM]{2,}\z~u', $array);
}


Simple usage:

echo "&lt;pre&gt;";
   print_r(delValByLessOld($words));
echo "&lt;/pre&gt;";


Output:

Array
(
    [0] =&gt; ӯтар
    [1] =&gt; ӯро
    [2] =&gt; ӯт
    [3] =&gt; ғариб
    [4] =&gt; афтода
    [5] =&gt; даст
    [6] =&gt; ра
)


My new (updated) function:

function delValByLess(&amp;$array, $less = 2, $lang = 'en')
{

    $search =  array('english','eng', 'russian', 'rus', 'tajik', 'taj', 'tjk');
    $replace = array('en', 'en', 'ru', 'ru', 'tj', 'tj', 'tj');

    if(is_string($lang))
    {
        $lang = mb_strtolower($lang);
        $lang = str_replace($search, $replace, $lang);
    }

    if(is_array($lang))
    {
        foreach ($lang as $lan) 
        {
            $lan = mb_strtolower($lan);
            $lang[$lan] = str_replace($search, $replace, $lan);
        }
    }

    $languages = 
    [
        'en' =&gt; 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM',
        'ru' =&gt; 'ёйцукенгшщзхъфывапролджэячсмитьбюЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ',
        'tj' =&gt; 'ғӯқҳҷӣҒӮҚҲҶӢ'
    ];

    if (is_array($array) &amp;&amp; is_numeric($less)) 
    {
        if(is_string($lang))
        {
            if (isset($languages[$lang]))  
            {
                return preg_grep('~\A[^'.$languages[$lang].']{'.$less.',}\z~u', $array);
            }
        }

        if(is_array($lang))
        {
            foreach ($lang as $lan)
            {
                if (isset($languages[$lan]))  
                {
                    $array = preg_grep('~\A[^'.$languages[$lan].']{'.$less.',}\z~u', $array);
                }
            }

            return $array;
        }
    }

    return false;   
}


Simple usage:

echo "&lt;pre&gt;";
   print_r(delValByLess($words,'3', ['ENGLISH','TAJIK']));
echo "&lt;/pre&gt;";


Output:

Array
(
    [4] =&gt; афтода
    [5] =&gt; даст
)
It took me a while to decipher what you meant with 'less than n values'. What your function actually does: it filters out all words that are either shorter than the specified length (less) or contain any character from the specified language(s).


The function name is very undescriptive. In a small project that may not be an issue, but in larger projects it quickly becomes impossible to remember what every piece of code does. A good name allows you to quickly understand what a function does. A poor name often requires you to look at how it's implemented, which takes a lot more time. What about removeShortAndForeignWords?
The same goes for parameter and variable names. Good names make code easier to understand: $array -> $words, $less -> $minimumLength, $lang -> $languageCode, $languages -> $languageFilters, and so on.
Why do you try to parse language names? That's very difficult to get right (what if I wanted to use American English, or ру́сский?), so the effect is that your function becomes less reliable, not easier to use. It's much more effective to just document which language codes your function supports (en, ru and tj). In a statically typed language I'd use an enum, but here a set of constants should do.
$lang[$lan] = str_replace($search, $replace, $lan); - Here, because you use $lan as a key, you're adding entries. If the input was array('en', 'ru'), you end up with array('en', 'ru', 'en' =&gt; 'en', 'ru' =&gt; 'ru'), which results in double work (the filters for each language are executed twice).
if(is_array($lang)) - Use else if here.
qwertyuiopasdfghjklzxcvbnm matches a specific keyboard layout, but abcdefghijklmnopqrstuvwxyz is a much more natural order for latin characters. However, since you're using a regex, you can simply use a-zA-Z.
You can remove a lot of code duplication by making your function recursive. If $lang is an array, then your function can call itself (once for every language code in the array) and then return the final result. Then the rest of the code doesn't need to take multiple language codes into account anymore.
The return value behavior of your function is inconsistent. If you pass an invalid language code, it returns false. However, if you pass an array of invalid language codes, it returns the input words array.
Personally I'd be very careful with references in PHP (&amp;$array). I've seen some surprising edge-cases and as far as I know they often degrade performance. In this case, your function is both returning a filtered array, and it's updating the original array (but only if you pass an array of language codes). So in your last example, not only does the output contain 2 russian words, $words has also been replaced with the results array. That's a very surprising side-effect.




As per your request, here's how I would probably have written it. I don't often work with PHP, and I haven't thoroughly tested this, but it should give you a reasonable impression:

const LANG_EN = 'en';
const LANG_RU = 'ru';
const LANG_TJ = 'tj';

/**
 * Takes an array of words and filters out any words that are too short or that contain any characters from the specified language(s).
 *
 * @param array $words The array of words to filter
 * @param number $minimumLength The minimum allowed word length
 * @param string|array $languageCode The language(s) that must be filtered out. The following languages are supported: LANG_EN, LANG_RU and LANG_TJ.
 *
 * @return array The given words, excluding words that are too short and words that are from the specified language(s).
 */
function removeShortAndForeignWords($words, $minimumLength = 2, $languageCode = LANG_EN) {
    if (is_array($languageCode)) {
        foreach ($languageCode as $language) {
            $words = removeShortAndForeignWords($words, $minimumLength, $language);
        }
        return $words;
    }

    $languageFilters = [
        LANG_EN =&gt; '[^a-zA-Z]',
        LANG_RU =&gt; '[^ёйцукенгшщзхъфывапролджэячсмитьбюЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ]',
        LANG_TJ =&gt; '[^ғӯқҳҷӣҒӮҚҲҶӢ]',
    ];
    if (!isset($languageFilters[$languageCode])) {
        return false;
    }

    return preg_grep('~\A'.$languageFilters[$languageCode].'{'.$minimumLength.',}\z~u', $words);
}