Curious if anyone has a cool snippet or idea for how to accomplish the following:
/**
* Select all of the keys matching a given key. Asterisks (*)
* should be treated as wildcards and would match any string
* similar to a regex expression: 'test_*_asdf' => 'test_.+_asdf'
*
* @param string $wild_key
* @param array $array
* @return array
*/
array_key_exists_wildcard($wild_key, $array);
Obviously it would be nice to just replace * with .+, but special characters could cause a problem, right? I also couldn’t come up with a graceful solution using explode.
function array_key_exists_wildcard ( $arr, $nee )
{
$nee = str_replace( '*', '###star_needle###', $nee );
$nee = preg_quote( $nee, '/' ); # This is important!
$nee = str_replace( '###star_needle###', '.*?', $nee );
$nee = '/^' . $nee . '$/i';
return preg_grep( $nee, array_keys( $arr ) );
}
$arr = array(
'file_1224rf_meh.jpg' => 111,
'file_506640_jones.jpg' => 555
);
var_dump( array_key_exists_wildcard( $arr, 'file_*_jones.jpg' ) );
My Attempt.
<?php
/**
* @desc ...
*
* @param String $sWildKey
* @param Array $aArray
* @return Array
*/
function array_key_exists_wildcard($sWildKey, $aArray)
{
$sPattern = sprintf(
'~%s~',
str_replace('\\*', '(.{1})', preg_quote($sWildKey))
);
$aFinal = array();
foreach ($aArray as $mKey => $mValue)
{
if(preg_match($sPattern, $mKey))
{
$aFinal[$mKey] = $mValue;
}
}
return $aFinal;
}
$aArray = array(
'Foo' => 'Bar',
'Bar' => 'Foo'
);
print_r(array_key_exists_wildcard('F*', $aArray));
/*
Array
(
[Foo] => Bar
)
*/
print_r(array_key_exists_wildcard('Ba*', $aArray));
/*
Array
(
[Bar] => Foo
)
*/
?>
logic, you continue to amaze me preg_quote is really good to know; thanks for the tip.
Thanks for the attempt too Silver.
Could simplify it of course…It only returns the keys (case-insenitive…) that match.
function array_key_exists_wildcard ( $arr, $nee )
{
$nee = str_replace( '\\*', '.*?', preg_quote( $nee, '/' ) );
return preg_grep( '/^' . $nee . '$/i', array_keys( $arr ) );
}
If you want the keys and values:
function array_key_exists_wildcard ( $arr, $nee )
{
$nee = str_replace( '\\*', '.*?', preg_quote( $nee, '/' ) );
$nee = preg_grep( '/^' . $nee . '$/i', array_keys( $arr ) );
return array_intersect_key( $arr, array_flip( $nee ) );
}