How to return only named groups with preg_match or preg_match_all?

rsk82 picture rsk82 · Jul 18, 2010 · Viewed 13.4k times · Source

Example:

$string = "This is some text written on 2010-07-18.";
preg_match('|(?<date>\d\d\d\d-\d\d-\d\d)|i', $string, $arr_result);
print_r($arr_result);

Returns:

Array
(
    [0] => 2010-07-18
    [date] => 2010-07-18
    [1] => 2010-07-18
)

But I want it to be:

Array
(
    [date] => 2010-07-18
)

In PHP's PDO object there is an option that is filtering results from database by removing these duplicate numbered values : PDO::FETCH_ASSOC. But I haven't seen similar modifier for the PCRE functions in PHP yet.

Answer

Jens A. Koch picture Jens A. Koch · Jan 11, 2016

How to return only named groups with preg_match or preg_match_all?

This is currently (PHP7) not possible. You will always get a mixed type array, containing numeric and named keys.

Lets quote the PHP manual (http://php.net/manual/en/regexp.reference.subpatterns.php):

This subpattern will then be indexed in the matches array by its normal numeric position and also by name.


To solve the problem the following code snippets might help:

1. filter the array by using an is_string check on the array key (for PHP5.6+)

$array_filtered = array_filter($array, "is_string", ARRAY_FILTER_USE_KEY);

2. foreach over the elements and unset if array key is_int() (all PHP versions)

/**
 * @param array $array
 * @return array
 */
function dropNumericKeys(array $array)
{
    foreach ($array as $key => $value) {
        if (is_int($key)) {
            unset($array[$key]);
        }
    }
    return $array;
}

Its a simple PHP function named dropNumericKeys(). Its for the post-processing of an matches array after a preg_match*() run using named groups for matching. The functions accepts an $array. It iterates the array and removes/unsets all keys with integer type, leaving keys with string type untouched. Finally, the function returns the array with "now" only named keys.

Note: The function is for PHP downward compatiblity. It works on all versions. The array_filter solution relies on the constant ARRAY_FILTER_USE_KEY, which is only available on PHP5.6+. See http://php.net/manual/de/array.constants.php#constant.array-filter-use-key