Wildcard match on array keys

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(
        '~&#37;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
)
*/
?>

:slight_smile:

logic, you continue to amaze me :smiley: 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 ) );
}

:slight_smile: