A shorter way to run a match on the array's keys rather than the values:
<?php
function preg_grep_keys($pattern, $input, $flags = 0) {
return array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags)));
}
?>(PHP 4, PHP 5, PHP 7, PHP 8)
preg_grep — Retorna entradas de array que correspondem à expressão regular
Retorna o array consistindo dos elementos do parâmetro
array que correspondem à expressão regular informada em
pattern.
patternA expressão a ser pesquisada, como uma string.
arrayO array de entrada.
flags
Se definido para PREG_GREP_INVERT, esta função retornará
os elementos do array de entrada que não correspondem
ao pattern informado.
Retorna um array indexado usando as chaves do parâmetro
array, ou false em caso de falha.
Se o padrão de expressão regular passado não for compilado para uma expressão regular válida, um E_WARNING será emitido.
Exemplo #1 Exemplo de preg_grep()
<?php
$array = [ "4", M_PI, "2.74", 42 ];
// retorna todos os elementos do array contendo número em ponto flutuante
$fl_array = preg_grep("/^(\d+)?\.\d+$/", $array);
var_dump($fl_array);
?>
A shorter way to run a match on the array's keys rather than the values:
<?php
function preg_grep_keys($pattern, $input, $flags = 0) {
return array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags)));
}
?>Run a match on the array's keys rather than the values:
<?php
function preg_grep_keys( $pattern, $input, $flags = 0 )
{
$keys = preg_grep( $pattern, array_keys( $input ), $flags );
$vals = array();
foreach ( $keys as $key )
{
$vals[$key] = $input[$key];
}
return $vals;
}
?>This may be obvious to most experienced developers,but just in case its not,when using preg_grep to check for whitelisted items ,one must be very careful to explicitly define the regex boundaries or it will fail
<?php
$whitelist = ["home","dashboard","profile","group"];
$possibleUserInputs = ["homd","hom","ashboard","settings","group"];
foreach($possibleUserInputs as $input)
{
if(preg_grep("/$input/i",$whitelist)
{
echo $input." whitelisted";
}else{
echo $input." flawed";
}
}
?>
This results in:
homd flawed
hom whitelisted
ashboard whitelisted
settings flawed
group whitelisted
I think this is because if boundaries are not explicitly defined,preg_grep looks for any instance of the substring in the whole array and returns true if found.This is not what we want,so boundaries must be defined.
<?php
foreach($possibleUserInputs as $input)
{
if(preg_grep("/^$input$/i",$whitelist)
{
echo $input." whitelisted";
}else{
echo $input." flawed";
}
}
?>
this results in:
homd flawed
hom flawed
ashboard flawed
settings flawed
group whitelisted
in_array() will also give the latter results but will require few tweaks if say,the search is to be case insensitive,which is always the case 70% of the time